精华内容
下载资源
问答
  • where 用到的字段没创建索引,就不走索引。下面这三种情况也会走索引。where field1 like '%abc%' --like %where substr(field1,1)='a' --函数where field1 in ('a','b','c') --in索引列有函数处理或隐式转换,不走...

    where 用到的字段没创建索引,就不走索引。

    下面这三种情况也会走索引。

    where field1 like '%abc%' --like %

    where substr(field1,1)='a' --函数

    where field1 in ('a','b','c') --in

    索引列有函数处理或隐式转换,不走索引

    索引列倾斜,个别值查询时,走索引代价比走全表扫描高,所以不走索引

    索引列没有限制 not null,索引不存储空值,如果不限制索引列是not null,oracle会认为索引列有可能存在空值,所以不会按照索引计算)

    1、查询谓词没有使用索引的主要边界,可能会导致不走索引。比如,你查询的是SELECT * FROM T WHERE Y=XXX;假如你的T表上有一个包含Y值的组合索引,但是优化器会认为需要一行行的扫描会更有效,这个时候,优化器可能会选择TABLE ACCESS FULL,但是如果换成了SELECT Y FROM T WHERE Y = XXX,优化器会直接去索引中找到Y的值,因为从B树中就可以找到相应的值。

    2、如果在B树索引中有一个空值,那么查询诸如SELECT COUNT(*) FROM T 的时候,因为HASHSET中不能存储空值的,所以优化器不会走索引,有两种方式可以让索引有效,一种是SELECT COUNT(*) FROM T WHERE XXX IS NOT NULL或者是不能为空。

    3、如果在T表上有一个索引Y,但是你的查询语句是这样子SELECT * FROM T WHERE FUN(Y) = XXX。这个时候索引也不会被用到,因为你要查询的列中所有的行都需要被计算一遍,因此,如果要让这种sql语句的效率提高的话,在这个表上建立一个基于函数的索引,比如CREATE INDEX IDXFUNT ON T(FUN(Y));这种方式,等于Oracle会建立一个存储所有函数计算结果的值,再进行查询的时候就不需要进行计算了,因为很多函数存在不同返回值,因此必须标明这个函数是有固定返回值的。

    4、索引不适用于隐式转换的情况,比如你的SELECT * FROM T WHERE Y = 5 在Y上面有一个索引,但是Y列是VARCHAR2的,那么Oracle会将上面的5进行一个隐式的转换,SELECT * FROM T WHERE TO_NUMBER(Y) = 5,这个时候也是有可能用不到索引的。

    5、在Oracle的初始化参数中,有一个参数是一次读取的数据块的数目,比如你的表只有几个数据块大小,而且可以被Oracle一次性抓取,那么就没有使用索引的必要了,因为抓取索引还需要去根据rowid从数据块中获取相应的元素值,因此在表特别小的情况下,索引没有用到是情理当中的事情。

    6、很长时间没有做表分析,或者重新收集表状态信息了,在数据字典中,表的统计信息是不准确的,这个情况下,可能会使用错误的索引,这个效率可能也是比较低的。

    在《Oracle专家编程》这本书中,有一个非常不错的例子,在本机实际做一下,能对索引有一个更深的印象,大致就是

    CREATE TABLE FOO(USERNAME VARCHAR2(100) PRIMARY KEY,USERID VARCHAR2(100));

    产生一堆数据,然后查询SQL

    CREATE TABLE FOOBAK SELECT * FROM FOO ORDER BY USERID DESC;

    然后给USERNAME加上主键索引,然后查询SQL

    能够看到两个使用了USERNAME pk  的索引,产生了不同的执行计划,这个实实在在的说明了表的物理结构实实在在的影响了执行计划。

    展开全文
  • mysql 索引> 走不走索引

    千次阅读 2019-08-22 19:39:29
    < > 就是不走索引 联合索引 < 以后不走索引

    < > 就是不走索引
    在这里插入图片描述

    联合索引

    < 以后不走索引

    在这里插入图片描述

    展开全文
  • swx_order表和swx_order_provider表和swx_order_servicer表联查,where条件是last_modify_time,三张表的数据量都在40万以上,如下sql查询时间非常慢,而且主表(swx_order)时而走索引,时而不走索引,当last_...

    swx_order表和swx_order_provider表和swx_order_servicer表联查,where条件是last_modify_time,三张表的数据量都在40万以上,如下sql查询时间非常慢,而且主表(swx_order)时而走索引,时而不走索引,当last_modify_time时间区间很小时走索引,时间区间大之后就不走索引了,原因是如果加了索引的行数比较多,mysql的优化器会自动放弃索引而选择全表扫描

    详细解释参考:https://dev.mysql.com/doc/refman/5.5/en/index-hints.html

    优化思路:强制sql执行时使用索引,也就是不需要mysql的优化器去选择,通过use index和force index可以强制sql任何时间都走索引,优化后如图所示:

     

    添加force index之后发现都不走索引了,继续查找原因,发现只有单表的时候force index是有效的,继续测试发现是where条件后的or条件导致索引失效,因此采用union替换or的方式优化sql,结果如图所示:

     

    展开全文
  • 但是有些情况下,即使建立了索引,但是执行写出来的查询还是很慢,然后通过执行计划会发现是索引失效导致的(不走索引,走全表扫描)。所以需要了解一下有哪些些情况会导致索引失效,即查询不走索引的原因。在写SQL的...

    Oracle建立索引的目的是为了避免全表扫描,提高查询的效率。

    但是有些情况下,即使建立了索引,但是执行写出来的查询还是很慢,然后通过执行计划会发现是索引失效导致的(不走索引,走全表扫描)。所以需要了解一下有哪些些情况会导致索引失效,即查询不走索引的原因。

    在写SQL的层面上一些骚操作会导致索引失效

    没有写WHERE子句或查询条件没有建立索引

    既然没有WHERE子句,那么就是查询全部数据了,相当于全表扫描,当然不走索引了。

    而查询条件上没有建立索引的话,索引都没有还走个毛索引啊。

    WHERE子句上没有使用索引中的引导列

    要使用索引,则查询条件中必须包含索引中的引导列。比如一个复合索引包含A,B,C,D四列,则A为引导列(排在第一位置的列)。如果WHERE子句中所包含的列是BCD或者BD等情况,则只能使用非匹配索引扫描。

    --创建包含A,B,C,D四列的复合索引

    CREATE INDEX INDEX_ABCD ON LETTERS(A, B, C, D);

    --下列语句不会使用复合索引

    SELECT * FROM LETTERS WHERE B = 'b' AND C = 'c';SELECT * FROM LETTERS WHERE B = 'b' AND D = 'd';SELECT * FROM LETTERS WHERE C = 'c' AND D = 'd';SELECT * FROM LETTERS WHERE B = 'b' AND C = 'c' AND D = 'd';

    另外,单独引用复合索引里排第一位置的索引列也会导致索引失效,复合索引必须复合使用才能生效。

    --单独使用复合索引中的引导列也不会触发复合索引

    SELECT * FROM LETTERS WHERE A = 'a'

    WHERE子句中使用IS NULL或IS NOT NULL

    使用判断空或非空的条件会导致该索引列失效。

    --COMM列的索引会失效

    SELECT * FROM EMP WHERE COMM IS NULL;

    WHERE子句中使用函数

    如果没有使用基于函数的索引,那么WHERE子句中对存在索引的列使用函数时,会使优化器忽略这些索引。

    --在没有建立基于函数索引的字段上使用了函数,会导致索引失效

    SELECT * FROM STUFF WHERE TRUNC(BIRTHDAY) = '2019-04-01'

    非要这样的话可以通过在索引列上建立基于函数的索引来解决问题。

    --给BIRTHDAY列创建TRUNC函数的函数索引

    CREATE INDEX STUFF_BIRTHDAY_FBI_IDX ON STUFF(TRUNC(BIRTHDAY));

    这样的话函数索引就起作用了,也就能在索引列上使用函数了,而且这时候你想不用函数都不行。

    但是对于MIN,MAX函数等,Oracle仍然会使用索引,因为Oracle对这类聚合分析函数做了相应的优化。

    对索引列进行运算导致索引失效

    和使用函数同样的,如果使用运算,比如加减乘除非等,也会导致索引失效。

    --对索引列进行了减法运算,导致不走索引

    SELECT * FROM USERS WHERE AGE - 1 = 23

    --正确的写法(去除运算)

    SELECT * FROM USERS WHERE AGE = 24

    使用前导模糊查询

    前导模糊查询的写法是LIKE '%T',即通配符【%】写在要匹配的字符前面,这样的情况下不走索引。

    --前导模糊查询不走索引

    SELECT * FROM LOVERS WHERE NAME LIKE '%静';

    WHERE子句中使用不等于条件

    不等于操作包括:

    <>

    !=

    NOT COL >=?NOT COL <= ?

    为什么不等于条件会不走索引,我们可以用常规的思维去推断一下。首先【不等于】这个概念可以推断成选取结果集中的一个比较大的部分,比如我们要找出中国人口中不是姓杨的,要找出资深程序员中不会秃头的,都可以认为是要返回结果集中一个很大的部分。因为Oracle的CBO是闭源的,我们只能推断Oracle会认为既然要返回结果集中很大的一个部分,不如直接使用全表扫描而不考虑索引。

    而且Oracle是建议,对于这些限制条件可以使用OR代替,例如COL <> 0可以替换成COL > 0 OR COL < 0。

    WHERE子句中使用NOT IN或NOT EXISTS

    使用NOT IN或NOT EXISTS也会导致不走索引。

    事实上NOT IN和NOT EXISTS也可以看做是不等于条件,不走索引的原因和上面的不等于条件相同。

    另外有一些人说使用IN是不走索引的,这是不对的,IN是可以走索引的,只是可能效率会比EXISTS低。

    等于和范围索引不会被合并使用

    SELECT * FROM CARS WHERE COLOR = 'yellow' AND TYPE = 'B'

    在上面的查询中,COLOR和TYPE列上都创建了非唯一索引,在这种查询条件下Oracle并不会合并索引,而只会使用第一个索引,即只有COLOR列上索引会生效。

    比较不匹配类型的数据类型

    比如SERIAL_CODE是一个VARCHAR2类型的字段,在这个字段上建立了索引,但是下面的语句将会执行全表扫描而不走索引。

    SELECT * FROM MATERIALS WHERE SERIAL_CODE = 810646874;

    为什么呢?因为Oracle中有一个字段自动进行隐式类型转换的机制,会自动把类型不匹配的字段进行隐式类型转换,相当于:

    SELECT * FROM MATERIALS WHERE TO_NUMBER(SERIAL_CODE) = 810646874;

    可以看出,Oracle优化器自动给SERIAL_CODE加上了类型转换函数,这样就限制了索引的使用。

    所以正确的写法应该是条件和字段类型相匹配:

    SELECT * FROM MATERIALS WHERE SERIAL_CODE = '810646874';

    表中数据量的多少也会影响索引的使用

    查询的数量是大表的大部分,应该是30%以上

    如果查询的数量超过大表数量的30%,那就不走索引了。

    对小表查询

    举个极端的例子,表中只有一条数据,何必走索引呢。比如你看一本只有几页的书,难道你还会去看目录吗,给这本书建目录都是人才了,你还去找这本书有没有目录岂不是人才中的人才(你别去上班了,我建目录养你啊)。

    索引失效的解决办法

    下面这些解决办法是基于SQL写得没问题,而索引就是不生效的情况。

    选用合适的Oracle优化器

    Oracle的优化器有三种,一种是基于规则的(RULE),一种是基于成本的(COST),还有一种是选择性的(CHOOSE)。

    在缺省的情况下(未设置),Oracle默认采用CHOOSE优化器。为了避免那些不必要的全表扫描(FULL TABLE SCAN),你必须尽量避免使用CHOOSE优化器,而直接采用基于规则或基于成本的优化器。

    重建索引

    和电脑出了问题的重启试试一样,索引出了问题也是可以重建试试的。

    ALTER INDEX 索引名 REBUILD

    强制索引

    强制索引是使用hint关键字。

    正常使用的索引突然失效的对应解决办法

    有些时候,同样的SQL,之前是能走索引的,突然有一天不走索引了,那么可能是:

    1.随着表的增长,WHERE条件出来的数据太多,大于15%,导致CBO计算出走索引扫描大于走全表扫描,就会使得索引失效。这种情况目前我也不知道该怎么办(好难啊)。

    2.统计信息失效。这种情况需要重新搜集统计信息。

    3.索引本身失效。这种情况就很玄乎了,只能重建索引试试。

    "人始终要走到某个路口,看着一路的同伴有些往左走,有些往右走,只剩下自己一个左顾右盼,不知所措。要么跟着大部队往左往右,要么就朝前走,绝没有任何退后的可能。"

    展开全文
  • 查询在什么时候不走索引参考回答主要三种情况1 >不满足走索引的条件, 常见的情况有1.1 >不满足最左匹配原则1.2 >查询条件使用了函数1.3>or 操作有一个字段没有索引1.4 >使用 like 条件以 % 开头2 >...
  • oracle 不走索引

    千次阅读 2019-04-12 17:02:01
    今天加了个简单数据,结果走计划分析没有走索引。 搜了一圈后,发现,因为返回的数据量很大,大概3分之一。...所以不走索引。 如果只是查询对应的索引字段,还是走索引,包含了其他的字段的话,就是走全表。 ...
  • 在Oracle数据库操作中,为什么有时一个表的某个字段明明有索引,当观察一些语的执行计划确不走索引呢?如何解决呢?本文我们主要介绍这部分内容,接下来让我们一起来了解一下。  不走索引大体有以下几个原因: ...
  • 在一些业务场景中,会使用NOT EXISTS语句确保返回数据不存在于特定集合,部分同事会发现NOT EXISTS有些场景性能较差,甚至有些网上谣言说”NOT EXISTS不走索引”,哪对于NOT EXISTS语句,我们如何优化呢?...
  • mysql中不走索引的情况 * 本次总结是建立在mysql 8这个版本上的。 ** 先上一个关于mysql explain分析后,type的各种类型解释,要注意每种type的效率谁高谁低。 1、索引列 参与 计算 select name from user ...
  • sql不走索引案例

    2021-01-12 16:19:06
    sql不走索引案例 查询视图 select count(1) from VI_ALL_ORDER vi where vi.DECLARATIONAPPLY_ACTUAL between to_date('2020-11-01', 'yyyy-mm-dd') and to_date('2020-12-21', 'yyyy-mm-dd'); 此查询时间维护...
  • 不走索引的情况

    千次阅读 2017-04-09 13:46:12
    1、条件字段选择性弱,查出的结果集较大,不走索引; 2、where条件等号两边字段类型不同,不走索引; 3、优化器分析的统计信息陈旧也可能导致不走索引; 4、索引字段 is null 不走索引; 5、对于count(*)当索引...
  • SQL不走索引的情况

    千次阅读 2018-04-04 11:29:24
    1、条件字段选择性弱,查出的结果集较大,不走索引; 2、where条件等号两边字段类型不同,不走索引; 3、优化器分析的统计信息陈旧也可能导致不走索引; 4、索引字段 is null 不走索引; 5、对于count(*)当索引...
  • oracel 字段不走索引

    2018-05-06 15:05:33
    用oracle做全表查询时发现一个问题,如果数据库某个varchar2类型的字段建了索引,但是查询的时候扔进入的值是long或integer类型的数据,oracle会不走索引,oracle会对传入的参数做to_char()处理,所以不会走索引。...
  • 当前找工作,对于一定年限的软件开发者,都会被问到索引的相关问题,最近我发现对于mysql数据库中in关键字走不走索引,有很多面试者回答的都不贴切。为了后面索引分析,我们先简单介绍下mysql中的explain语句,方便...
  • select 建立了索引但是不走索引

    千次阅读 2018-06-22 15:55:22
    create index indexName on A(abc);此时select abc from A 不走索引。。。。可用如下方法让搜索走索引select distinct(abc) from A a where exists (select 1 from A b where a.abc=b.abc)红色部分必须一致。...
  • 同样的sql ,在不同的数据库上,执行效率不一致现象:mysql版本5.7数据库引擎 innoDB...走索引的数据情况A表的数据为4w条B表的数据为23条查询时间0.3秒不走索引的数据情况A表的数据为4w条B表的数据为5条查询时间13秒A...
  • 同事遇到一个奇葩的问题,一个表里某个字段建了索引,但是有的值走索引,有的值不走索引。因为一般情况一个字段要么完全不走索引,要么走索引,怎么会有的值走索引,有的不走索引。select 条件非常简单,因为涉及到...
  • 如题 请问mysql 为什么like不走索引,全部模糊查询,为何前面不模糊就可以走索引。
  • like百分号加前面一定不走索引吗?正常来讲,我们都知道在mysql的like查询中,百分号加在关键词后面是走索引的,比如 select * like "张三%",而百分号在前面是不走索引的,比如 select * like "%张三",但也有例外...
  • 破坏索引(不走索引)的SQL

    千次阅读 2018-09-12 17:21:50
    1.[转载] 全表扫描 2. [转载] 不走索引
  • like百分号加前面一定不走索引吗?正常来讲,我们都知道在mysql的like查询中,百分号加在关键词后面是走索引的,比如 select * like "张三%",而百分号在前面是不走索引的,比如 select * like "%张三",但也有例外...
  • MySql Delete不走索引问题

    千次阅读 2019-10-03 21:44:05
    如果delete语句带有查询,写法不对会导致不走索引。 简单粗暴的办法:拆两条sql,一条查询,一条delete ======================= 【不走索引的写法】 DELETE FROM goods_item_combo_group_item_history WHERE...
  • 不走索引的原因

    千次阅读 2014-12-15 12:37:30
    补充:不走索引的原因,甚至加上hint 还不走索引,那可能是因为你要走索引的这列是nullable,虽然这列没有空值。(将字段改为not null) 备注 : 不走索引的其它原因 1、建立组合索引,但查询谓词并未使用...
  • 在一些业务场景中,会使用NOT EXISTS语句确保返回数据不存在于特定集合,部分同事会发现NOT EXISTS有些场景性能较差,甚至有些网上谣言说”NOT EXISTS不走索引”,哪对于NOT EXISTS语句,我们如何优化呢?...
  • Mysql 之 索引的作用 以及 不走索引的情况 写一下mysql索引吧,提及索引失效的原因的时候,当初只记得两个,虽然笔记有,当时的脑子可能是这样的。 温故而知新,看一遍不如写一遍 1. 为什么要创建索引 没有加...
  • 关于update in不走索引的:首先select子查询形式是走索引的如下所示:select * from acct_trans_payment where autopayflag='N' and objectno in(select serialno from acct_loan where businessstatus='1' and ...
  • 网上有很多人说in不走索引,事实上我经过执行计划自己测试发现,in明明就是走索引的。看来网上也不全可信啊。后来又查了以下,发现 MySQL 4.1 以上版本的 IN 是走索引的, 但4.0及其以下版本是不走索引的。 原来是...
  • 但是有些情况下,即使建立了索引,但是执行写出来的查询还是很慢,然后通过执行计划会发现是索引失效导致的(不走索引,走全表扫描)。所以需要了解一下有哪些些情况会导致索引失效,即查询不走索引的原因。 在写...
  • 关于sqlserver in 走不走索引

    千次阅读 2016-09-08 11:48:41
    先看图 看懂了吗,当数据量较少时,没有走索引。当插入10万数据之后,走了索引。大多数说 in 不走索引,可能就在于测试的时候插入的数据量不多导致的吧~
  • 今天在做SQL Tuning的时候遇到一个典型的example,立个Flag,梳理知识点,在这里也做个分享,就是我们在写SQL的时候如果对索引字段使用函数炒作,则导致该SQL不走索引扫描查询,导致SQL性能下降。 SQL如下: SELECT ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,563
精华内容 1,025
关键字:

不走索引