欢迎访问shiker.tech

请允许在我们的网站上展示广告

您似乎使用了广告拦截器,请关闭广告拦截器。我们的网站依靠广告获取资金。

SQL索引的优先级
(last modified Oct 15, 2022, 12:33 AM )
by
侧边栏壁纸
  • 累计撰写 176 篇文章
  • 累计创建 61 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

SQL索引的优先级

橙序员
2022-09-21 / 0 评论 / 0 点赞 / 746 阅读 / 644 字 / 正在检测百度是否收录... 正在检测必应是否收录...
文章摘要(AI生成)

mysql在索引使用的时候一般都会把数据最小的字段放前面,也就是最能确定结果的字段,因为索引的第一个字段的检索范围是最小的,然后根据可以确定的数据范围的大小依次排序.这个时候不要担心sql里使用字段的顺序是不是和索引里一样,mysql在查询的时候会自动调整顺序优化成和索引一样的顺序.场景应用实际应用

mysql在索引使用的时候一般都会把数据最小的字段放前面,也就是最能确定结果的字段,因为索引的第一个字段的检索范围是最小的,然后根据可以确定的数据范围的大小依次排序.这个时候不要担心sql里使用字段的顺序是不是和索引里一样,mysql在查询的时候会自动调整顺序优化成和索引一样的顺序.

场景应用

实际应用中,假设我们有一张指令的表,存储不同调用系统的通讯指令。我们需要坐一个巡检来查询某一指令在最近3个月的未完成的结果。

涉及的表结构为:

image-20220921163739435

为了巡检我们需要定位按时间范围确定我们要查找遍历的数据范围,即获取最大最小ID记录;

获取最小id的sql如下:

image-20220921164116367

可以看到查询时长达14s,我们查看解析这条sql:

image-20220921164218953

可以看到这条sql走的索引是我们指令类型的索引。

为什么会这样呢?

我们将单个条件拉出来一次查看对应的扫描行数:

created_time>‘2022-06-21’:扫描495w行

image-20220921164441488

inst_type = ‘2’:扫描302w行

image-20220921170350318

biz_line in (3,15):扫描2095w行:

image-20220921170454057

怎么解决?

解决这个问题有两种方式:

1、改单索引为聚合索引:

ALTER TABLE `cashcow_birch`.`divided_account_inst` 
ADD INDEX `dix_type_biz_time`(`inst_type`, `biz_line`, `created_time`);

这样我们在查询时,会命中我们的联合索引,导致我们扫描行数大幅减小

image-20220921170950308

2、缩小查询范围,在不改变原有业务语义的场景下,由于我们现在是获取扫描范围的最小边界,所以可以将时间范围缩小为三个月前的那一天来获取边界值:

select * from divided_account_inst WHERE (created_time > '2022-06-21' and created_time < '2022-06-22' and inst_type = '2' and biz_line in ( 3 , 15 ) and data_source_flag = 0 ) limit 1

我们解析这条sql,发现扫描行数减少到5.6w行

image-20220921173756895

总结

1、在多条件查询时,mysql会优先取扫描行数最少的索引作为该查询的使用索引。

2、在条件查询时,我们的查询条件扫描行数越小,查询时间越少

0

评论区