① EXPLAIN SELECT * FROM employees WHERE age = 22 AND position = 'manager';
② EXPLAIN SELECT * FROM employees WHERE position = 'manager';
③ EXPLAIN SELECT * FROM employees WHERE name = 'LiLei';
④ EXPLAIN SELECT * FROM employees WHERE name = 'LiLei' AND position = 'manager';
分析:
①中的where条件后面age=22不是索引的最左前列,后面就不用看了,没有命中索引,②也是如此。
③中的name是索引idx_name_age_position的最左前列,命中索引。
④中的name命中索引,position没有命中索引,因为跳过索引中的age列,中间断了,age列还是需要全表扫描。
(3)不要在索引列上做任何操作(如计算、函数、自动或手动类型转换),否则会导致索引失效而转向全表扫描
执行SQL语句:EXPLAIN SELECT * FROM employees WHERE LEFT(name, 3)='LiLei'
(4)存储引擎不能使用索引中范围条件右边的列
执行SQL语句:EXPLAIN SELECT * FROM employees WHERE AND age>22 AND position='manager'
分析:长度为78,name为74,age是int类型,所以为4,即只有name和age命中索引,position没有命中索引,因为它属于age范围条件右边的索引列。
(5)尽量使用覆盖索引(只访问索引的查询,索引列包含查询列),减少 select * 语句
执行SQL语句:EXPLAIN SELECT name,age FROM employees WHERE
执行SQL语句:EXPLAIN SELECT * FROM employees WHERE
(6)MySQL在使用不等于(!= 或者 <>)的时候无法使用索引,会导致全表扫描
执行SQL语句:EXPLAIN SELECT * FROM employees WHERE name != 'LiLei'
(7)is null,is not null也无法使用索引
执行SQL语句:
EXPLAIN SELECT * FROM employees WHERE name IS NULL
(8)like以通配符开头('$abc'),MySQL索引会失效导致全表扫描
执行SQL语句:EXPLAIN SELECT * FROM employees WHERE name LIKE '%Lei'
执行SQL语句:EXPLAIN SELECT * FROM employees WHERE name LIKE 'Lei%'
提问:如何解决like '%字符串%' 索引没有命中?
① 使用覆盖索引,查询字段必须是建立覆盖索引字段
执行SQL语句:EXPLAIN SELECT name,age,position FROM employees WHERE name LIKE '%Lei%'
② 当覆盖索引指向的字段是varchar(380)及以上的字段时,覆盖索引会失效!
(9)字符串不加单引号,索引失效(内部会做一个字符串转换函数)
执行SQL语句:EXPLAIN SELECT * FROM employees WHERE name=1000
(10)少用or或in,用它查询时,非主键字段的索引会失效,主键索引有时生效,有时不生效,跟数据量有关,具体还得看MySQL的查询优化结果
执行SQL语句:EXPLAIN SELECT * FROM employees WHERE OR
总结:
like KK% 相当于等于常量,%KK 和 %KK% 相当于范围。
Linux公社的RSS地址:https://www.linuxidc.com/rssFeed.aspx