通过前两章的学习,其实可以说:一个sql写的好不好,快不快,完全取决于索引是否用的上,不失效 ,这章通过大量的例子来讲述如何避免索引失效.
总结:
一。 全值匹配我最爱
二。 最佳左前缀法则 (如果索引了多列,要遵守最左前缀法则。指的是查询从索引的最左前列开始并且不能跳过索引中的列)
三。不在索引列上做任何操作(计算 函数 (自动or手动)的类型转换) ,会导致索引失效而转向全局扫描
四。存储引擎不能使用索引中范围条件右边的列(范围之后全失效)
五。 尽量使用覆盖索引(在第二章提到过)
六。mysql 在使用不等于 (!= 或者 <>)的时候 无法使用索引 会导致全表扫描
七。is null,is not null也无法使用索引
八。 like 以通配符开头('%abc')mysql索引失效会变成全表扫描
九。字符串不加单引号索引失效
![](/qrcode.jpg)
十。 少用or 用它来连接时会索引失效
例子:
以下内容没有特殊生命均为索引123
一:
(1)SELECT * FROM WHERE 2='a' AND 3='c'
产生:未使用索引 type=ALL ref=NULL
(2)SELECT * FROM WHERE 1='A' AND 3=’c‘
产生:只使用了第一列的索引
二:
(1)SELECT * FROM WHERE 1='a'
产生:一切正常
(2)SELECT * FROM WHERE left(1,4)='a' (left函数中第一行代表索引1的列)
产生:索引失效
三:
(1)SELECT * FROM WHERE1='A' AND 2='B' AND 3='C'
产生:一切正常
(2)SELECT * FROM WHERE1='A' AND 2> 10 AND 3='C'
产生:没有使用到3的索引
四:
(1)SELECT * FROM WHERE 1='a'
产生:正常
(2)SELECT * FROM WHERE 1 != 'a'
产生:索引失效
(3)SELECT * FROM WHERE 1 IS NULL
产生:索引失效
五:
(1)SELECT * FROM WHERE 1 LIKE '%A%'
产生:索引失效
(2)SELECT * FROM WHERE 1 LIKE '%A'
产生:索引失效
(3)SELECT * FROM WHERE 1 LIKE 'A%'
产生:type=range
tips:覆盖索引可以解决模糊查询的索引失效问题
六
(1)SELECT * FROM WHERE 1=A
产生:索引失效
(2)SELECT * FROM WHERE 1='A'
产生:正常使用
tips:在字符串字段上不加引号 会调用mysql的自动类型转换导致索引失效
七
SELECT * FROM WHERE 1='A' OR 1='B'
产生:索引失效
总结:
WHERE语句 | 索引是否被使用 |
WHERE a=3 | 使用到a |
WHERE a=3 and b=5 | 使用到 a b |
WHERE a=3 and b=4 and c=5 | 使用到 abc |
where b=3 或where b=3 and c=4 或where c=4 | 索引失效 |
where a=3 and c=5 | 使用到a |
where a=3 and b>4 and c=5 | 使用到a b |
where a=3 and b like 'k%' and c= 4 | 使用到 abc |
where a=3 and b like '%k' and c=4 | 使用到 a |
where a=3 and b like '%k%' and c=4 | 使用到 a |
where a =3 and b like 'kk%kk%' and c=4 | 使用到 abc |
优化口诀总结
全值匹配我最爱,最左前缀要遵守
带头大哥不能死,中间兄弟不能断
索引列上少计算,范围之后全失效
LIKE百分写最右,索引覆盖不写星
不等空值还有or,索引失效要少用