Explain详解与索引优化实践(5)

① 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

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/e29ab88dd33cafa3b0071b471ee0ab56.html