MySQL高级之查询优化(索引失效)
文章目录
一、单表使用索引及常见的索引失效
1.索引失效的案例
-
全值匹配我最爱 -
全值匹配指的是我要
查询的语句的字段顺序恰好和建立的索引的字段顺序一致,否则索引失效 -
最佳左前缀法则 -
如果索引了多列(覆盖索引),要遵守最左前缀法则,指的是查询从索引的最左前列开始并且不跳过索引中的列
-
不在索引列上做任何操作 -
这里的任何操作包括计算、函数、(自动or手动)类型转换,会导致索引失效而转向全表扫描
-
存储引擎不能使用索引中的范围条件右边的列 -
mysql在使用不等于(!=或者<>)的时候无法使用索引导致全表扫描 -
is null,is not null也无法使用索引(这种说法不唯一,综合考察SQL语句所涉及表的索引、数据分布、统计信息,才能综合判断,用通俗的话来说要结合具体场景) -
like以通配符开头(’%abc…’)索引失效会变成全表扫描 -
字符串不加单引号索引失效 -
少用or,用它来连接时会索引失效
小总结:
2.建议
-
对于单键索引,尽量选择针对当前query过滤性更好的索引 -
在选择组合索引的时候,当前query中过滤性最好的字段在索引字段顺序中,位置越靠前越好 -
在选择组合索引的时候,尽量选择可以能够包含当前query中的where子句中更多字段的索引 -
尽可能通过分析统计信息和调整query的写法来达到选择合适索引的目的
优化总结口诀:
- 全值匹配我最爱,最左前缀要遵守;
- 带头大哥不能死,中间兄弟不能断;
- 索引列上少计算,范围之后全失效;
- LIKE百分写最右,覆盖索引不写星;
- 不能空值还有OR,索引失效要少用;
- VAR引号不可丢,SQL高级也不难;
二、关联查询优化
1.建表
2.案例
3.优化
保证驱动表的join字段已被索引left join时选择小表作为驱动表,大表作为被驱动表inner join时,mysql会自己帮你把小结果的表作为驱动表子查询尽量不要放在被驱动表,有时可能使用不到索引能够直接多表关联的尽量直接多表关联,不用子查询
三、子查询优化
-
尽量不要使用not in或者not exist,用left join ... on替换exist
四、排序分组优化
1.case
2.order by子句,尽量使用Index方式排序,避免使用FileSort排序
3.索引的选择
4.如果不在索引列上,firesort有两种算法:双路排序和单路排序
-
双路排序 -
单路排序 -
结论和问题 -
由于单路是后出的,比双路排序好
-
用单路的问题:
-
优化策略 -
原理: