MySQL索引优化二

索引优化实践

前提条件

  • 上篇MySQL索引优化一介绍了索引中Explain的使用,下要介绍在日常开发中的使用。
  • 先要准备表格数据,本文章讨论案例的表结构如下,读者可以自行插入10条以上的数据来模拟下面的各种情况,数据太少有些情况出不来预期结果。
drop table if exists test;
create table test(
	id int auto_increment primary key,
	a varchar(32),
    b varchar(32),
    c varchar(32),
	key idx_abc(a,b,c)
) engine=innodb charset=utf8mb4;

多场景实践

等值查询交换位置

  • 在进行等值查询的时候,改变查询顺序不能改变Explain的执行计划,因为后台优化器会优化执行,但是推荐还是按照索引的顺序来查询
mysql> -- 执行等值查询
mysql> explain select * from test where a = '1' and b = '1' and c = '1';
+----+-------------+-------+------+---------------+----------+---------+-------------------+------+--------------------------+
| id | select_type | table | type | possible_keys | key      | key_len | ref               | rows | Extra                    |
+----+-------------+-------+------+---------------+----------+---------+-------------------+------+--------------------------+
|  1 | SIMPLE      | test  | ref  | idx_abcd      | idx_abcd | 393     | const,const,const |    1 | Using where; Using index |
+----+-------------+-------+------+---------------+----------+---------+-------------------+------+--------------------------+
1 row in set (0.00 sec)

mysql> -- 交换位置查询
mysql> explain select * from test where a = '1' and c = '1' and b = '1';
+----+-------------+-------+------+---------------+----------+---------+-------------------+------+--------------------------+
| id | select_type | table | type | possible_keys | key      | key_len | ref               | rows | Extra                    |
+----+-------------+-------+------+---------------+----------+---------+-------------------+------+--------------------------+
|  1 | SIMPLE      | test  | ref  | idx_abcd      | idx_abcd | 393     | const,const,const |    1 | Using where; Using index |
+----+-------------+-------+------+---------------+----------+---------+-------------------+------+--------------------------+
1 row in set (0.00 sec)

比较列右边的索引全失效

  • 从下图的执行情况可以看出比较列后面的列失效,因为key_len明显减少了一个列的长度。但是如果比较列在最后是没有影响的。
  • 画外音:单列的key_len=4n+2+1,其中n是字段的长度,因为是varchar类型长度+2,因为可以为null,长度+1
    - 调整列的顺序,比较在最后的索引列可以用到所有的索引列
    在这里插入图片描述

最佳左前缀

  • 下图只用了一个索引列,从Extra信息可以看出排序的时候使用了索引Using index,c没有用上。说明了中间列如果断开之后后面的索引列就用不上了(中间兄弟不能断)
    在这里插入图片描述- 如果按照顺序来执行,从key_len明显可以看出前面两个索引用在查询上,第三个索引用在了排序上
    在这里插入图片描述- 如果是跳过中间索引来执行排序,从下图可以看出出现了Using filesort,排序的索引失效了。
    在这里插入图片描述

排序中使用索引

  • 顺序使用索引列,从下图可以看出key_len中使用了一个索引列,而其它的两列b、c出现在排序中,但是并没有出现Using filesort说明排序也要满足最佳左前缀原则
    在这里插入图片描述- 交换排序字段为order by c,b,查询索引没有改变,但是出现了Using filesort,不符合最佳做前缀原则
    在这里插入图片描述- 索引列同时出现在查询和排序时。查询列使用了索引,排序的时候使用了索引,并没有产生Using filesort
    在这里插入图片描述- 排序方式不一致导致索引失效,日常使用中需要保证索引的排列方式一致
    在这里插入图片描述- in查询:由于有多个等值条件也相当于范围查询,这个时候后面的索引失效。
    在这里插入图片描述

分组中索引的使用

  • 查询的key_len为两个字段的长度,没有出现排序。说明分组索引生效。
    在这里插入图片描述- 如果分组的时候不是按照索引的顺序来进行分组,如下图的第二种场景,会出现Using filesort,而第一种是按照索引的顺序来查询没有出现Using filesort
    在这里插入图片描述

总结

  • MySQL支持两种方式的排序Using filesortUsing index,Using index是指MySQL扫描索引本身完成排序。index效率高,filesort效率低。
  • order by满足两种情况会使用Using index。
    • order by语句使用索引最左前列。
    • 使用where子句与order by子句条件列组合满足索引最左前列。
  • 尽量在索引列上完成排序,遵循索引建立(索引创建的顺序)时的最佳左前缀法则。
  • 如果order by的条件不在索引列上,就会产生Using filesort。
  • group by与order by很类似,其实质是先排序后分组,遵照索引创建顺序的最佳左前缀法则
  • where优先过滤 能写在where中的限定条件就不要去having限定。

欢迎可以关注spring-cloud系列 openfeign hystrix打怪升级系列性能优化系列
你的点赞和关注是我创作的最大动力,有什么不足和错误的地方欢迎留言!可以微信搜索关注【小二说码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值