本文问题

什么是Index Merge?Index Merge的限制有哪些?

如何查看语句是否使用了Index Merger?

Index Merge有哪几种?分别适用于那些情景?

如何控制优化器是否使用Index Merge

Index Merge 索引合并

索引合并检索方法可以检索多个范围扫描并将结果合并。这种访问方法只能合并同一个表的索引扫描,不能合并跨表扫描。

合并可能生成基础扫描结果的"并集","交集",或者"交集的并集"

示例:

SELECT * FROM tbl_name WHERE key1 = 10 OR key2 = 20;

SELECT * FROM tbl_name

WHERE (key1 = 10 OR key2 = 20) AND non_key = 30;

SELECT * FROM t1, t2

WHERE (t1.key1 IN (1,2) OR t1.key2 LIKE 'value%')

AND t2.key1 = t1.some_col;

SELECT * FROM t1, t2

WHERE t1.key1 = 1

AND (t2.key1 = t1.some_col OR t2.key2 = t1.some_col2);

Index Merge的已知缺陷

如果在WHERE语句中,存在多层嵌套的AND/OR,MySQL可能不会选择最优的方案,可以尝试通过拆分WHERE子句的条件来进行转换:

(x AND y) OR z => (x OR z) AND (y OR z)

(x OR y) AND z => (x AND z) OR (y AND z)

Index Merger不能应用于全文索引(fulltext index)

Index Merge的EXPLAIN输出

type列的值显示为index_merge

key列显示使用的索引列表

key_len列显示这些索引的最大长度(列表)。

Extra列显示Index Merge的算法:

Using intersect(...)

Using union(...)

Using sort_union(...)

mysql> explain select * from test_merge where (col1<10 and col2>50) or col3=50;

+----+-------------+------------+------------+-------------+---------------+---------------+---------+------+------+----------+----------------------------------------------+

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |

+----+-------------+------------+------------+-------------+---------------+---------------+---------+------+------+----------+----------------------------------------------+

| 1 | SIMPLE | test_merge | NULL | index_merge | idx_1_2,idx_3 | idx_1_2,idx_3 | 5,5 | NULL | 214 | 100.00 | Using sort_union(idx_1_2,idx_3); Using where |

+----+-------------+------------+------------+-------------+---------------+---------------+---------+------+------+----------+----------------------------------------------+

1 row in set, 1 warning (0.00 sec)

mysql> explain select * from test_merge where (col1=10 and col2=50) or col3=50;

+----+-------------+------------+------------+-------------+---------------+---------------+---------+------+------+----------+-----------------------------------------+

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |

+----+-------------+------------+------------+-------------+---------------+---------------+---------+------+------+----------+-----------------------------------------+

| 1 | SIMPLE | test_merge | NULL | index_merge | idx_1_2,idx_3 | idx_1_2,idx_3 | 10,5 | NULL | 22 | 100.00 | Using union(idx_1_2,idx_3); Using where |

+----+-------------+------------+------------+-------------+---------------+---------------+---------+------+------+----------+-----------------------------------------+

1 row in set, 1 warning (0.00 sec)

Index Merge 算法

Index Merge Intersection 索引合并交集

这种方法适用于WHERE子句中的条件是通过AND结合的不同索引的范围条件时,其中的每个条件都需要满足下列条件之一:

如果其中的索引是多列索引,条件中需要包括索引的所有列

key_part1 = const1 AND key_part2 = const2 ... AND key_partN = constN

在Innodb表的主键上的范围条件

示例:

SELECT * FROM innodb_table

WHERE primary_key < 10 AND key_col1 = 20;

SELECT * FROM tbl_name

WHERE key1_part1 = 1 AND key1_part2 = 2 AND key2 = 2;

索引合并交集算法在所有使用的索引上同时进行扫描,并从扫描结果中生成行的交集

如果查询中的所有列都被使用的索引覆盖,不需要检索所有表行(EXPLAIN输出中的Extra列中包括Using index)。例如这个语句:

SELECT COUNT(*) FROM t1 WHERE key1 = 1 AND key2 = 1;

如果使用的索引没有覆盖查询中所有的行,只有当所有使用的索引的范围条件满足时才检索整个行。

如果合并条件中包括Innodb表主键索引条件,主键并不用来检索数据,而是用来筛选使用其他条件检索出的行。 # 就是先通过其他的范围条件筛选出一部分数据,在从这部分数据中,通过主键来筛选出最终的结果

Index Merge Union 索引合并并集

这种方法适用于WHERE子句中的条件是通过OR结合的不同索引的范围条件时,其中的每个条件都需要满足下列条件之一:

如果其中的索引是多列索引,条件中需要包括索引的所有列

key_part1 = const1 AND key_part2 = const2 ... AND key_partN = constN

在Innodb表的主键上的范围条件

适用于Index Merger intersection算法的条件

示例:

SELECT * FROM t1

WHERE key1 = 1 OR key2 = 2 OR key3 = 3;

SELECT * FROM innodb_table

WHERE (key1 = 1 AND key2 = 2)

OR (key3 = 'foo' AND key4 = 'bar') AND key5 = 5;

Index Merge Sort_Union

这种方法适用于WHERE子句中的条件是通过OR结合的不同索引的范围条件,但是不能使用Index Merge Union算法的情景

示例:

SELECT * FROM tbl_name

WHERE key_col1 < 10 OR key_col2 < 20;

SELECT * FROM tbl_name

WHERE (key_col1 > 10 OR key_col2 = 20) AND nonkey_col = 30;

sort_union和union算法的区别是,sort_union必须在返回行数据前先获取行ID并对行ID进行排序。

禁用Index Merge

在optimizer_swith中有4个关于Index Merge的变量:

index_merge,index_merge_intersection,index_merge_union,index_merge_sort_union

默认情况下都是启用的。要单独启用某个算法,设置index_merge=off,并将相应的标志设置为on

问题答案

什么是Index Merge?Index Merge的限制有哪些?

如果查询中使用到了不同的索引,可以对不同索引的条件分别进行范围扫描,然后将扫描结果合并得到最终的结果,这就是Index Merge。

限制:只能合并同一个表的索引扫描结果,不能跨表合并。此外,无法对fulltext索引进行合并

如何查看语句是否使用了Index Merge?

EXPLAIN中type列的值为index_merge表示使用了索引合并。根据索引合并算法的不同,会在Extra列中显示Using intersect/union/sort_union

Index Merge有哪几种?分别适用于那些情景?

3种:Intersection,Union,Sort_union

Intersection:使用AND结合的关于不同索引的条件(普通索引的等值表达式或者主键索引的范围表达式)

Union和Sort Union:使用OR结合的关于不同索引的范围条件

区别:当条件为普通索引的等值表达式或者主键索引的范围表达式时,可以使用Union。其他不符合条件的只能使用Sort Union

如果包括多列索引,在范围条件中需要包括索引中的所有列。

如何控制优化器是否使用Index Merge

在optimizer_swith中有4个关于Index Merge的变量:

index_merge,index_merge_intersection,index_merge_union,index_merge_sort_union

默认情况下都是启用的。要单独启用某个算法,设置index_merge=off,并将相应的标志设置为on

mysql 索引合并_MySQL 索引合并(Index Merge)优化相关推荐

  1. mysql gis index 索引原理_Mysql 索引原理及优化

    Mysql 索引原理及优化 什么是索引 为什么需要索引? 索引是数据表种一个或者多个列进行排序的数据结构 索引能够大幅提升检索速度 创建.更新索引本身也会耗费空间和时间 查找结构进化史 线性查找:一个 ...

  2. mysql merge查询速度_MySQL 查询优化之 Index Merge

    MySQL 查询优化之 Index Merge 索引合并访问方法可以在查询中对一个表使用多个索引,对它们同时范围扫描,并且合并结果(intersects/unions/unions-of-inters ...

  3. mysql设置id值为索引值_MySQL 索引

    一.索引作用 提供了类似于书中目录的作用,目的是为了优化查询 (一).索引种类 1.B树索引(Balance Tree) 作用 Btree的设计理念,就是让查询能够快速锁定范围,特别适合于范围查询. ...

  4. mysql多索引结构_MySQL 索引结构

    谈到 MYSQL 索引服务端的同学应该是熟悉的不能再熟悉,新建表的时候怎么着都知道先来个主键索引,对于经常查询的列也会加个索引加快查询速度.那么 MYSQL 索引都有哪些类型呢?索引结构是什么样的呢? ...

  5. 讴 mysql 首字母_MYSQL索引

    什么是索引? 举个例子:新华字典,有目录,有正文内容.索引就相当于目录,正文内容就相当于数据. 索引有什么用? 索引用于快速查找在某列中有一特定值的行. 一条查询语句,如果没有索引,将对全表进行扫描. ...

  6. mysql 子查询索引失效_mysql 索引失效的情况

    索引失效的几种情况 1.如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因) 要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引 2.对于多列索引,不是使用 ...

  7. mysql 视图会走索引吗_MySQL索引和视图

    一.什么是索引? 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针.更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度 ...

  8. mysql多列索引用处_MySQL索引使用说明(单列索引和多列索引)

    1. 单列索引 在性能优化过程中,选择在哪些列上创建索引是最重要的步骤之一.可以考虑使用索引的主要有两种类型的列:在Where子句中出现的列,在join子句中出现的列.请看下面这个查询: 这个查询与前 ...

  9. mysql 索引语法_MySQL 索引:语法及案例剖析

    MySQL 索引 MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度. 打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索 ...

最新文章

  1. Linux初学者的感受
  2. 12月21 vs2012 数据类型
  3. [css] H5如何禁止显示系统菜单?
  4. SQL Server死锁
  5. 【README】回溯算法基本框架
  6. Games101 计算机图形学课程笔记: Lecture14 Ray Tracing 2
  7. 冬天来了,温暖甜品热饮海报设计psd模板,勾住你的胃!
  8. 【可行】adb修改手机代理方式
  9. 突击计划——求整数中的较大者
  10. java解析搜狗词库scel文件到txt
  11. newtonsoft.json java,Newtonsoft.Json无法反序列化有效的JSON
  12. Emmagee——开源Android性能测试工具
  13. CDN - 原理解析
  14. Python3,5行代码让电脑永不息屏。
  15. STM32互补PWM输出使能控制
  16. excel筛选栏显示各项数量_excel筛选显示数量
  17. 服务器禁止用ip访问站点,windows服务器禁止ip访问方法介绍
  18. 【最优化导论】一维搜索方法案例
  19. Leaflet 和 Cesium 加载纠偏后高德地图在线瓦片,高德地图最新最全在线瓦片地址
  20. Mac 下用Homebrew安装Go

热门文章

  1. 循环删除List集合的错误
  2. 使用Collections.emptyList()生成的List不支持add方法___Java Collections.emptyList方法的使用及注意事项
  3. java文件下载出现文件名乱码解决办法
  4. linux sh expr冒号,linux expr命令参数及用法详解
  5. 计算机专业需要学好的数学知识,学好数学对计算机专业重要吗?
  6. java仿聊天室项目总结_Java团队课程设计-socket聊天室(Day4总结篇)
  7. mysql 删除not null_从MySQL的列中删除NOT NULL限制?
  8. android--多线程,android多线程
  9. c语言数组转置原理,为什么这个数组转置不对?
  10. 域内计算机如何同步网络t时间,网络节点的同步方法