1.隐式转换导致索引失效.这一点应当引起重视.也是开发中经常会犯的错误.
由于表的字段tu_mdn定义为varchar2(20),但在查询时把该字段作为number类型以where条件传给Oracle,这样会导致索引失效.
错误的例子:select * from test where tu_mdn=13333333333;
正确的例子:select * from test where tu_mdn=‘13333333333’;
2. 对索引列进行运算导致索引失效,我所指的对索引列进行运算包括(+,-,*,/,! 等)
错误的例子:select * from test where id-1=9;
正确的例子:select * from test where id=10;
3. 使用Oracle内部函数导致索引失效.对于这样情况应当创建基于函数的索引.
错误的例子:select * from test where round(id)=10; 说明,此时id的索引已经不起作用了
4. 以下使用会使索引失效,应避免使用;
a. 使用 <> 、not in 、not exist、!=
b. like “%_” 百分号在前(可采用在建立索引时用reverse(columnName)这种方法处理)
c. 单独引用复合索引里非第一位置的索引列.应总是使用索引的第一个列,如果索引是建立在多个列上, 只有在它的第一个列被where子句引用时,优化器才会选择使用该索引。
d. 字符型字段为数字时在where条件里不添加引号.
e. 当变量采用的是times变量,而表的字段采用的是date变量时.或相反情况。
5. 不要将空的变量值直接与比较运算符(符号)比较。
如果变量可能为空,应使用 IS NULL 或 IS NOT NULL 进行比较,或者使用 ISNULL 函数。
6. 不要在 SQL 代码中使用双引号。
因为字符常量使用单引号。如果没有必要限定对象名称,可以使用(非 ANSI SQL 标准)括号将名称括起来。
索引使用原则:
在根据执行计划对SQL进行分析之后,逐步的去优化每个子查询的索引及成本使用情况,执行计划我的理解就是用来对索引进行逐步的优化的一个过程,让每个查询都尽量使用索引,在索引过程中,索引会经常性失效。
口诀
全值匹配我最爱,最左前缀要遵守
带头大哥不能死,中间兄弟不能断
索引列上少计算,范围之后全失效
LIKE符号写最右,覆盖索引不写星
不等空值还有or,索引失效要少用
var引号不能丢,SQL高级也不难
分组之前必排序,一定要上索引啊
建索引注意事项
1、单值索引,尽量选择过滤性更好的字段,例如:性别字段,过滤度为50%,识别率很差,不建议建索引
2、组合索引,索引字段的顺序可以按照识别度进行排序,识别度越高,放在越靠前
3、组合索引,尽量包含where语句中的更多字段
4、尽可能的根据分析执行计划、统计信息,去调整query的写法达到合适索引的目的
索引容易失效的几个注意点
1、不在索引列上做任何的操作(计算、函数、类型转换),会导致索引失效而转向全表扫描
2、组合索引中,如果中间某个字段使用了范围条件,则右边的列索引失效
3、尽量使用覆盖索引(索引列和查询列一致),减少使用select *
4、mysql在使用不等于(!= 或者<>)的时候,无法使用索引列会导致全表扫描
5、is null ,is not null 也无法使用索引
6、like通配符必须放在索引列的右边,否则索引失效,编程全表扫描
7、字符串不加单引号索引失效
8、少用or,用它连接索引会失效