MySQL 优化之 index_merge (索引合并)

文章目录

  • 一、案例
  • 二、优化
  • 三、知识点
    • 1.为什么会有index merge
    • 2.对 index merge 的进一步优化

一、案例

生产某个接口调用时间超过了5s,排查发现,是由于某个sql执行需要2~3s左右,接口中执行了两次该sql,对接口代码及sql进行优化后,接口执行时间缩短到1s左右。特此记录:
sql如下:

SELECT ID, COUPONS_CODE, BATCH_ID, IS_SOLD, IS_USED, DEPT_ID
FROM cc_coupons
WHERE BATCH_ID = 115 AND IS_SOLD = 0;

查看cc_coupons表索引

show index from cc_coupons;


explain + sql查看执行计划
在这里插入图片描述
在cc_coupons表中,BATCH_ID、IS_SOLD 为单值索引

select count(1) from cc_coupons where BATCH_ID = 115; #结果为20000行
select count(1) from cc_coupons where IS_SOLD = 0; #结果为660W行

在网上查找index_merge相关知识后,发现index_merge其实就是分别通过对两个独立的index进行过滤之后,将过滤之后的结果聚合在一起,然后在返回结果集。在该sql中,由于IS_SOLD字段的过滤性不好,故返回的rows依然很多,所以造成的很多的磁盘read,导致了cpu的负载非常的高,直接就出现了延迟。

二、优化

创建复合索引idx_batchId_isSold

create index idx_batchId_isSold on cc_coupons(BATCH_ID, IS_SOLD);

在这里插入图片描述
查看执行计划
在这里插入图片描述
type变为了ref,比index的效率要高

三、知识点

1.为什么会有index merge

我们的 where 中可能有多个条件(或者join)涉及到多个字段,它们之间进行 AND 或者 OR,那么此时就有可能会使用到 index merge 技术。index merge 技术如果简单的说,其实就是:对多个索引分别进行条件扫描,然后将它们各自的结果进行合并(intersect/union)

MySQL5.0之前,一个表一次只能使用一个索引,无法同时使用多个索引分别进行条件扫描。但是从5.1开始,引入了 index merge 优化技术,对同一个表可以使用多个索引分别进行条件扫描。

2.对 index merge 的进一步优化

index merge使得我们可以使用到多个索引同时进行扫描,然后将结果进行合并。听起来好像是很好的功能,但是如果出现了 index intersect merge,那么一般同时也意味着我们的索引建立得不太合理,因为 index intersect merge 是可以通过建立 复合索引进行更一步优化的。

参考
[1]: http://blog.itpub.net/28939273/viewspace-2154349/
[2]: https://www.cnblogs.com/digdeep/p/4975977.html

你可能感兴趣的:(MySQL,mysql,数据库,sql)