原标题:SQL无法走索引的情况及解决思路
上次丁俊大师在社群上做了CBO优化器和坑爹案例的分享后,反响不是一般的强烈,但其中也有一部分同学表示太高大上了(我也是这样觉得的),消化起来相当有难度,于是便有了本文。绕开复杂的CBO优化器不说,本文将帮你理清那些因为SQL语句编写规范问题导致没有充分利用索引来大幅提升效率的使用场景。
一、SQL无法走索引的情况及解决思路
因为数据库优化器不够智能,或者一些逻辑原因,导致SQL在比较适合走索引的情况下却无法正确利用索引。这时候,除了给数据库需要的统计信息之外,SQL语句本身还必须要给优化器足够多的额外有效信息,帮助优化器能够选择更好的执行计划。要让优化器正确选择需要的索引,要考虑两点:
如何避免优化器的限制根据业务数据特点改写SQL语句
说明:这里说的走不了索引,是指走不了正常的RANGE SCAN,非(FAST) FULL INDEX SCAN。
SQL无法走索引常见的有如下8种情况:
统计信息不准确索引列的值允许为NULL谓词使用了不等于(<>, !=)LIKE前通配或全通配的查询索引列使用了函数、数学运算、其它表达式等使用了隐式类型转换查询转换失败其它语句逻辑原因
第一、二种情况在现实中比较常见,解决办法也相对比较简单,下面就不再作详细展开了。
谓词使用了不等于(<>,!=),走不了索引
解决方法:
如果不等条件之外的值不多,而且是确定的,可以改为等值或IN查询,比如status状态字段一般值类别很少;如果不等条件之外的值很多,可以改为“> OR
举个例子,先构建测试场景:
谓词使用<>,无法利用索引:
将<>改写为OR连接后,能够正确使用索引,走OR扩展:
如果业务允许,改写为下列语句也是走索引的,不再演示。
SELECT * FROM t WHERE t.NAME IN (‘ORADB1′,’ORADB2′,’ORADB3’);
LIKE前通配或全通配的查询,走不了索引
解决方法,有如下三种:
(1)根据业务需求,是否可以把前通配去掉
原来全通配,无法走索引:
把前通配去掉,改为后通配,可以正常使用索引: