深入理解 index merge 是使用索引进行优化的重要基础之一。理解了 index merge 技术,我们才知道应该如何在表上建立索引。

1. 为什么会有index merge

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

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

相关文档:http://dev.mysql.com/doc/refman/5.6/en/index-merge-optimization.html (注意该文档中说的有几处错误)

The Index Merge method is used to retrieve rows with several range scans and to merge their results into one. The merge can produce unions, intersections, or unions-of-intersections of its underlying scans. This access method merges index scans from a single table; it does not merge scans across multiple tables.

In EXPLAIN output, the Index Merge method appears as index_merge in the type column. In this case, the key column contains a list of indexes used, and key_len contains a list of the longest key parts for those indexes.

index merge: 同一个表的多个索引的范围扫描可以对结果进行合并,合并方式分为三种:union, intersection, 以及它们的组合(先内部intersect然后在外面union)。

index merge 算法根据合并算法的不同分成了三种:intersect, union, sort_union.

2. index merge 之 intersect

简单而言,index intersect merge就是多个索引条件扫描得到的结果进行交集运算。显然在多个索引提交之间是 AND 运算时,才会出现 index intersect merge. 下面两种where条件或者它们的组合时会进行 index intersect merge:

3. index merge 之 union

简单而言,index uion merge就是多个索引条件扫描,对得到的结果进行并集运算,显然是多个条件之间进行的是 OR 运算。

下面几种类型的 where 条件,以及他们的组合可能会使用到 index union merge算法:

1) 条件使用到复合索引中的所有字段或者左前缀字段(对单字段索引也适用)

2) 主键上的任何范围条件

3) 任何符合 index intersect merge 的where条件;

上面三种 where 条件进行 OR 运算时,可能会使用 index union merge算法。

4. index merge 之 sort_union

This access algorithm is employed when the WHERE clause was converted to several range conditions combined by OR, but for which the Index Merge method union algorithm is not applicable.(多个条件扫描进行 OR 运算,但是不符合 index union merge算法的,此时可能会使用 sort_union算法)

5. index merge的局限

1)If your query has a complex WHERE clause with deep AND/OR nesting and MySQL does not choose the optimal plan, try distributing terms using the following identity laws:

6. 对 index merge 的进一步优化

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

7. 复合索引的最左前缀原则

上面我们说到,对复合索引的非最左前缀字段进行 OR 运算,是无法使用到复合索引的

SQL如下:
select cd.coupon_id, count(1) total from AAA cd
where  cd.coupon_act_id = 100476 and cd.deleted=0 and cd.pick_time is not null
group by cd.coupon_id ;

在AAA表中,coupon_act_id 和 deleted 都是独立的索引

select count(*) from AAA  where coupon_act_id = 100476;   结果为12360行

select count(*) from AAA where deleted=0;  结果为1300W行

从上面的解释我们可以看出来,index merge其实就是分别通过对两个独立的index进行过滤之后,将过滤之后的结果聚合在一起,然后在返回结果集。

在我们的这个例子中,由于deleted字段的过滤性不好,故返回的rows依然很多,所以造成的很多的磁盘read,导致了cpu的负载非常的高,直接就出现了延迟。

ps:其实在这个case中,并不需要加2个条件的index,只需要将deleted这个index干掉,直接使用coupon_act_id这个index即可,毕竟这个index的过滤的结果集已经很小了。

或者通过关闭index intersect功能也可以。

MySQL 优化之 index_merge (索引合并)的更多相关文章

  1. mysql 优化实例之索引创建

    mysql 优化实例之索引创建 优化前: pt-query-degist分析结果: # Query 23: 0.00 QPS, 0.00x concurrency, ID 0x78761E301CC7 ...

  2. MySQL优化器 --- index_merge

    [背景] 对于关系数据库中的一张表,通常来说数据页面的总大小要比较某一个索引占用的页面要大的多(上面说的索引是不包涵主键索引的); 更进一步我们可以推导出,如果我们通过读索引就能解决问题,那么它相比读 ...

  3. 0104探究MySQL优化器对索引和JOIN顺序的选择

    转自http://www.jb51.net/article/67007.htm,感谢博主 本文通过一个案例来看看MySQL优化器如何选择索引和JOIN顺序.表结构和数据准备参考本文最后部分" ...

  4. mysql优化-----多列索引的左前缀规则

    索引优化策略 :索引类型 .1B-tree索引 关注的是:Btree索引的左前缀匹配规则,索引在排序和分组上发挥的作用. 注:名叫btree索引,大的方面看都用的二叉树.平衡树.但具体的实现上,各引擎 ...

  5. mysql优化:覆盖索引(延迟关联)

    前言 上周新系统改版上线,上线第二天就出现了较多的线上慢sql查询,紧接着dba 给出了定位及解决方案,这里较多的是使用延迟关联去优化. 而我对于这个延迟关联也是第一次听说(o(╥﹏╥)o),所以今天 ...

  6. mysql优化工具(索引优化)

    mysql优化工具 1.pt-duplicate-key-checker(检查数据库的重复索引),这款工具可以帮助我们找到重复的索引并且还会给你删除重复索引的建议语句,非常好用. 2.

  7. Mysql优化系列之索引性能

    实际上,前面的数据类型和表结构设计优化不能算优化,只能算规范,也就是说在设计表的时候,应该且必须做到这些 索引是sql优化的核心部分,在<高性能Mysql>中单独抽出一章讲,也印证了其重要 ...

  8. 【mysql优化 2】索引条件下推优化

    原文地址:Index Condition Pushdown Optimization 索引条件下推(ICP:index condition pushdown)是mysql中一个常用的优化,尤其是当my ...

  9. MySQL优化之避免索引失效的方法

    在上一篇文章中,通过分析执行计划的字段说明,大体说了一下索引优化过程中的一些注意点,那么如何才能避免索引失效呢?本篇文章将来讨论这个问题. 避免索引失效的常见方法 1.对于复合索引的使用,应按照索引建 ...

随机推荐

  1. The Forth Week

    1.复制/etc/skel目录为/home/tuser1,要求/home/tuser1及其内部文件的属组和其它用户均没有任何访问权限. cp -r /etc/skell /home/tuser1 ; ...

  2. B - Oulipo

    The French author Georges Perec (1936�C1982) once wrote a book, La disparition, without the letter ' ...

  3. http-runtime属性

    配置httpRuntime也可以让FileUpload上传更大的文件,不过设置太大了会因用户将大量文件传递到该服务器而导致的拒绝服务攻击(属性有说明) 属性 属性 选项 说明 appRequestQu ...

  4. Codeforces Round #305 (Div. 2) C题 (数论)

    C. Mike and Frog time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  5. HDU 4509

    很简单的排序题而已. #include <iostream> #include <cstdio> #include <algorithm> #include < ...

  6. [Debug] Use Remote Sources to Debug a Web App on an Emulator, Simulator, or Physical Device

    We can emulate different operating systems, browsers, and devices within a desktop operating system. ...

  7. The superclass &quot;javax.servlet.http.HttpServlet&quot; was not found on the Java Build Path

    完整错误信息: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"AS IS" AND ANY ...

  8. 怎样在BIOS中设置RAID?

    随着价格的下降和相应主板的支持.眼下SATA硬盘已经逐渐成为主流. 但因为受芯片组和操作系统的影响.不少用户对SATA硬盘的使用及安装系统掌握不足,今天小编就给大家介绍一下SATA硬盘的日常应用技巧. ...

  9. 关于MySQL错误 2005 - Unknown MySQL server host 'localhost' (0) 原因及解决方法

    今天在外面开navicat for mysql的时候,怎么也连不上自己本机上的数据库,一直显示2005 - Unknown MySQL server host 'localhost' (0): 错误代 ...

  10. ExecutorCompletionService原理具体解释

    在JDK并发包中有这么一个类ExecutorCompletionService,提交任务后,能够按任务返回结果的先后顺序来获取各任务运行后的结果. 该类实现了接口CompletionService: ...