暂无图片
分享
czxin788
2020-09-16
请问mysql为什么选择了和我们想象不一样的索引了

1、sql的执行计划如下:

desc select   * from   live_message WHERE   msg_type = 18   and create_time > '2020-09-16 15:47:58.137' \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: live_message
   partitions: NULL
         type: range
possible_keys: idx_createtime_msgtype,idx_msg_type_id,idx_msg_type_create_time_id
          key: idx_msg_type_create_time_id
      key_len: 9
          ref: NULL
         rows: 2990
     filtered: 100.00
        Extra: Using index condition
1 row in set, 1 warning (0.00 sec)

2、看一下这个表的索引
image.png

3、很奇怪,为什么mysql选择的是idx_msg_type_create_time_id索引呢,而不选择idx_createtime_msgtype索引。
大家都说,在建立索引时,要把选择性高的字段放在前面,根据这个表,应该是create_time这个字段选择性高,理应是idx_createtime_msgtype这个联合索引是最佳选择。
可是,Mysql竟然选择了idx_msg_type_create_time_id 这个索引,要知道这个索引的msg_type做为第一个,他的选择性是不高的。
通过如下可以验证。
image.png

select count(*) from live_message where msg_type = 18 ;
+----------+
| count(*) |
+----------+
|    99307 |
+----------+
1 row in set (0.02 sec)

select count(*) from live_message where  create_time > '2020-09-16 15:47:58.137' ;
+----------+
| count(*) |
+----------+
|    24961 |
+----------+
1 row in set (0.01 sec)

4、请问,这是为什么呢

收藏
分享
3条回答
默认
最新
JiekeXu
暂无图片

你需要看一下 where 条件后的语句执行顺序就知道问题所在了。where …… and 应该也有执行顺序吧。

msg_type 和 create_time 字段并不能看倒哪个选择度高吧?

然后 msg_type 在前,create_time 在后,选择联合索引 idx_msg_type_create_time_id 就好说了,先选择 msg_type 就去找 msg_type 在前面的索引,而你说的 idx_createtime_msgtype 中 msg_type 应该在后面故没有用到,初学 MySQL 不知道这么理解合理吗?

暂无图片 评论
暂无图片 有用 0
文成

因为在mysql中,通过主键就可以获取整行记录,所以可能会先选择包含id列(主键)的索引
你可以试试以下的sql使用的是那个索引

select meg_type,create_time from live_message where msg_type=18 and create_time>'2020-09-16 15:47:58.137';
暂无图片 评论
暂无图片 有用 0
czxin788
问题已关闭: 问题已经得到解决
暂无图片 评论
暂无图片 有用 0
回答交流
提交
问题信息
请登录之后查看
邀请回答
暂无人订阅该标签,敬请期待~~
暂无图片墨值悬赏