【金三银四】Mysql执行计划EXPLAIN最佳实践

【MySql系列】文章导航

【金三银四】深刻理解MySql索引底层数据结构解密 juejin.im/post/5e0d7b…mysql

【金三银四】MySql执行计划EXPLAIN详解 juejin.im/post/5e12e4…sql

【金三银四】MySql执行计划EXPLAIN最佳实践 juejin.im/post/5e12e4…bash

【金三银四】MySql索引优化实战 juejin.im/post/5e12e5…数据结构

最佳实践

1. 全值匹配

EXPLAIN SELECT * FROM employees WHERE name= 'LiLei';

复制代码

图片

EXPLAIN SELECT * FROM employees WHERE name= 'LiLei' AND age = 22;

复制代码

图片

EXPLAIN SELECT * FROM employees WHERE name= 'LiLei' AND age = 22 AND position ='manager';

复制代码

图片

2.最左前缀法则

若是索引了多列,要遵照最左前缀法则。指的是查询从索引的最左前列开始而且不跳过索引中的列。函数

EXPLAIN SELECT * FROM employees WHERE age = 22 AND position ='manager';

复制代码

图片

EXPLAIN SELECT * FROM employees WHERE position = 'manager';

复制代码

图片

EXPLAIN SELECT * FROM employees WHERE name = 'LiLei';

复制代码

图片

3.不要在索引列上作任何操做(计算、函数、(自动or手动)类型转换),会致使索引失效而转向全表扫描

EXPLAIN SELECT * FROM employees WHERE name = 'LiLei';

复制代码

图片

EXPLAIN SELECT * FROM employees WHERE left(name,3) = 'LiLei';

复制代码

图片

4.存储引擎不能使用索引中范围条件右边的列

EXPLAIN SELECT * FROM employees WHERE name= 'LiLei' AND age = 22 AND position ='manager';

复制代码

图片

EXPLAIN SELECT * FROM employees WHERE name= 'LiLei' AND age > 22 AND position ='manager';

复制代码

图片

*5.尽可能使用覆盖索引(只访问索引的查询(索引列包含查询列)),减小select 语句

EXPLAIN SELECT name,age FROM employees WHERE name= 'LiLei' AND age = 23 AND position ='manager';

复制代码

图片

EXPLAIN SELECT * FROM employees WHERE name= 'LiLei' AND age = 23 AND position ='manager';

复制代码

图片

6.mysql在使用不等于(!=或者<>)的时候没法使用索引会致使全表扫描

EXPLAIN SELECT * FROM employees WHERE name != 'LiLei';

复制代码

图片

7.is null,is not null 也没法使用索引

EXPLAIN SELECT * FROM employees WHERE name is null;

复制代码

图片

8.like以通配符开头('$abc...')mysql索引失效会变成全表扫描操做

EXPLAIN SELECT * FROM employees WHERE name like '%Lei';

复制代码

图片

EXPLAIN SELECT * FROM employees WHERE name like 'Lei%';

复制代码

图片

问题:解决like'%字符串%'索引不被使用的方法?post

a)使用覆盖索引,查询字段必须是创建覆盖索引字段mysql索引

EXPLAIN SELECT name,age,position FROM employees WHERE name like '%Lei%';

复制代码

图片

b)当覆盖索引指向的字段是varchar(380)及380以上的字段时,覆盖索引会失效!优化

9.字符串不加单引号索引失效

EXPLAIN SELECT * FROM employees WHERE name = '1000';

复制代码

图片

EXPLAIN SELECT * FROM employees WHERE name = 1000;

复制代码

图片

10.少用or,用它链接时不少状况下索引会失效

EXPLAIN SELECT * FROM employees WHERE name = 'LiLei' or name = 'HanMeimei';

复制代码

图片

11.in和exsits优化

原则:小表驱动大表,即小的数据集驱动大的数据集ui

  • in:当B表的数据集必须小于A表的数据集时,in优于existsspa

    select * from A where id in (select id from B)

explain select * from film where id in(select film_id from film_actor);

复制代码

图片

  • exists:当A表的数据集小于B表的数据集时,exists优于in 将主查询A的数据,放到子查询B中作条件验证,根据验证结果(true或false)来决定主查询的数据是否保留 select * from A where exists (select 1 from B where B.id = A.id) #A表与B表的ID字段应创建索引
explain select * from film where exists (select 1 from film_actor where film_actor.film_id = film.id)

复制代码

图片

一、EXISTS (subquery)只返回TRUE或FALSE,所以子查询中的SELECT * 也能够是SELECT 1或select X,官方说法是实际执行时会忽略SELECT清单,所以没有区别

二、EXISTS子查询的实际执行过程可能通过了优化而不是咱们理解上的逐条对比

三、EXISTS子查询每每也能够用JOIN来代替,何种最优须要具体问题具体分析

总结

图片

like KK%至关于=常量,%KK和%KK% 至关于范围

相关文章
相关标签/搜索