MySQL 优化之 index_merge (索引合并)

深入理解 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功能也可以。

原文地址:https://www.cnblogs.com/hankyoon/p/11012620.html

时间: 2024-08-03 03:18:06

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

(2)mysql优化之使用索引优化查询

概述 ??索引是数据库优化中最常用的也是最重要的手段之一.该篇看看索引的分类,使用场景,不能使用的场景等. 索引分类 ??索引是在mysql存储引擎中实现的,而不是在服务器层实现的.索引每种存储引擎的索引不一定相同.mysql支持4种索引: B-tree索引:最常见索引,大部分引擎都支持B树索引. full-text索引:全文索引. hash索引:只有memory引擎支持. R-Tree索引:空间索引是myisam的一种特殊索引,使用比较少. 衍生索引:主键,唯一索引,组合索引,前缀索引等.ha

MySQL优化(5):索引失效分析、in与exists使用场合

一.索引失效的情况 前文提及过可以通过explain的possible_keys.key属性判断索引是否失效,key如果为null,可能是索引没建,也可能是索引失效,下面列举一些会使索引失效的情况. 1.全值匹配:顺序.个数与索引一致 2.最佳左前缀法则:查询从索引的最左前列开始并且不跳过索引中的列,中间跳过的值,后面的索引会失效 3.索引列上做了操作(计算.函数.自动或手动类型转换),会导致索引失效而转向全表扫描 4.存储引擎不能使用索引中范围条件右边的列 name字段用于查找,age>11也

Mysql优化系列之索引性能

实际上,前面的数据类型和表结构设计优化不能算优化,只能算规范,也就是说在设计表的时候,应该且必须做到这些 索引是sql优化的核心部分,在<高性能Mysql>中单独抽出一章讲,也印证了其重要性.这一篇也会讲的很细致. 以下所讲,除少数的如全文索引之外,均以Innodb存储引擎为基本 一.索引是什么 索引,在Mysql中也叫做"键(key)",是存储引擎用于快速找到记录的一种数据结构. 这里我们注意到:索引是一种数据结构,节点是有序的,有大小,有时候一张表的索引甚至会有几个G的

MySQL优化(2):索引简述

一.基本语法 创建索引前会先排序,会影响where和order by的效率. 索引也是一张表,保存了主键和索引字段和指向实体表的记录,也是要占空间的,以索引文件的形式存储在磁盘. 增删改数据时,索引指向也要改变,所以会慢,需要频繁删改的字段不适合建索引. 索引的建立也需要不断的优化.调整. 1.创建,两种写法 CREATE [UNIQUE] INDEX 索引名 ON 表(列1,列2); 主键索引:ALTER TABLE 表 ADD PRIMARY KEY (列); #添加一个主键,索引值必须唯一

Mysql 优化之延迟索引和分页优化

什么是延迟索引?使用索引查询出来数据,之后把查询结果和同一张表中数据进行连接查询,进而提高查询速度! 分页是一个很常见功能,select   **  from tableName limit  ($page -  1 )  * $n ,$n 通过一个存储过程进行测试: create table smth1 ( id int auto_increment , ver int(11) default null, content varchar(1000) not null, intro varcha

Mysql优化之BTree索引使用规则

从一道题开始分析: 假设某个表有一个联合索引(c1,c2,c3,c4)一下--只能使用该联合索引的c1,c2,c3部分 A where c1=x and c2=x and c4>x and c3=x B where c1=x and c2=x and c4=x order by c3 C where c1=x and c4= x group by c3,c2 D where c1=? and c5=? order by c2,c3 E where c1=? and c2=? and c5=? o

MySql优化-你的SQL命中索引了吗

在项目开发中SQL是必不可少的,表索也一样.这些SQL的运行性能不知道吗?有多少是命中了索引的?命中哪个索引?索引中有哪个是无效索引?这些无效索引是否会影响系统的性能?带着这些问题我们一起来学习一下. MySql中是通过 Explain 命令来分析低效SQL的执行计划.命令的使用很简单. 示例 explain select * from adminlog 执行结果: id select_type table partitjons type possible_keys key key_len re

mysql优化之索引

Mysql优化之使用索引 1,索引简介 索引是单独一种数据结构,单独存在的一个空间.可以把数据表里的建立了索引的字段,进和物理地址,存在在一块,这块空间就是'索引'. 查询数据先从索引中查询,查询到之后,可以直接定位到物理地址,通过物理地址,直接找到真实数据.查询会更快速. 索引是一种 以空间换时间的一种方式,牺牲了空间和写的速度,提高了查询速度 2,准备演示数据表 这里以myisam引擎的数据库为例,我准备了一张1800000条数据的表,这张表存储时包含了三个文件,.Frm是表结构文件,.MY

[MySQL优化] -- 如何查找SQL效率地下的原因

[MySQL优化] -- 如何查找SQL效率地下的原因   来源: ChinaUnix博客 日期: 2009.07.20 16:12 (共有条评论) 我要评论       查询到效率低的 SQL 语句 后,可以通过 EXPLAIN 或者 DESC 命令获取 MySQL 如何执行 SELECT 语句的信息,包括在 SELECT 语句执行过程中表如何连接和连接的顺序,比如我们想计算 2006 年所有公司的销售额,需要关联 sales 表和 company 表,并且对 profit 字段做求和( su