MySQL索引优化总结
作者 | SRE实战
来源 | 今日头条
保持独立列,不要用函数和运算
不要在列上使用函数,这将导致索引失效而进行全表扫描。
不要在列上进行运算,这也将导致索引失效而进行全表扫描。
避免隐式转换
当查询条件左右两侧类型不匹配的时候会发生隐式转换,隐式转换带来的影响就是可能导致索引失效而进行全表扫描。
select * from t where inta = "5" // 类型不匹配,隐式转换
索引不会包含有NULL的值
设计多列复合索引时一定要注意,所有列必须不能为null,因为含有null的列是不会被加入索引的,直接无效
这也是不允许null的一个因素
避免使用or连接,同列or可以转换为in
innodb对or的查询条件会运行多次单独的查询然后合并结果,时间复杂度为O(n),而对于In操作,innodb使用的是基于树的二分查找,时间复杂度为O(log n),显然In更快
适当利用覆盖索引加速
如果要查询的数据都在复合索引列中,那么就可以使用覆盖索引,直接查询到结果返回,省去“回表”
但要注意别把索引搞得太多或者太长,维护索引会降低性能
正确认识最左前缀匹配索引
对于使用最左前缀匹配索引,一定要注意必须从最左开始匹配才能利用上索引
对于使用最左前缀匹配索引,可以使用前n个匹配字段,也可以使用前m个匹配字符
一旦使用前缀匹配,那么将不能使用覆盖索引,也不能利用索引来排序或者group
复合索引顺序很重要
复合索引第一列不需要再次建立单列索引
order by和group by后面接的列与复合索引顺序一致时可以利用复合索引避免排序和临时表
范围查询会导致右侧条件索引失效
查询中的某个列有范围查询,则其右边所有列都无法使用索引优化查找。
升级Mysql到新的版本
这个看起来很搞笑,但真的很有用
5.6 的mysql加入了ICP、MRR、BKA
5.6 也优化了子查询,可以自动生成更快的查询,减少人为各种优化
5.7 整体性能改进,同时改进in、union、临时表,目前应该是最主流的版本
8.0+ 最新版本加入了Skip Scan access和hash join