Index Merge用在通过一些range scans得到检索数据行和合并成一个整体。合并可以通过 unions,intersections,或者unions-intersection运用在底层的扫描上。合并Index scans结果只能在一个表中,不能合并多张表的scans结果;

在explain执行计划输出中,index merge方法出现在 type 列,显示index merge,这种情况下key 列显示一列使用indexes,并且key_len列包含一列这些indexes 的最长部分;

Examples:

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 方法有许多access算法 ( Extra 列 Explain 输出):

Using intersect(...)

Using union(...)

Using sort_union(...)
   
    1:如果查询语句在含有复杂的内嵌的深度and / or where语句,Mysql不会选择最佳的执行计划,
(x AND y) OR z = (x OR z) AND (y OR z)
(x OR y) AND z = (x AND z) OR (y AND z)

2:index merge 不适用在full-text index;

The Index Merge Intersection Access Algorithm

    该access算法在运用在,当where子句中不同的index range conditions用 and 组合时:

1:index包括 N部分(所有index部分都包含):

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

2:  任何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;

Index merge intersection 算法同时在所有使用的indexes上执行scan,并且从合并的Index扫描中产生行序列的交集;

如果查询中的所有列都被使用的indexes所涵盖,完整的数据行不会被回访(只访问索引数据)(此时explain 输出包含显示using index 在extra列):

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

如果使用的indexes并不涵盖查询中的所有列,完整的数据行(基表的数据行)只会在范围条件被所有使用的Indexes都满足的情况下才会被回访;

如果在innodb table中,一个合并条件是在主键上,则他不会被使用在基表数据行的回访,被用在过滤其他条件回访返回的数据行;

index merge union access algorithm

该算法试用在表的where语句在不同的index上的不同范围条件的 Or 组合:

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 access algorithm

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 algorithm 和 the union algorithm 之间的区别在于必须首先获得所有的rows,并且对其排序被返回;

mysql> explain select * from employees where  emp_no < 257654 and hire_date = '1990-09-06';
+----+-------------+-----------+-------------+-------------------+-------------------+---------+------+------+-------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+-------------+-------------------+-------------------+---------+------+------+-------------------------------------------------+
| 1 | SIMPLE | employees | index_merge | PRIMARY,inx_hi_dt | inx_hi_dt,PRIMARY | 7,4 | NULL | 16 | Using intersect(inx_hi_dt,PRIMARY); Using where |
+----+-------------+-----------+-------------+-------------------+-------------------+---------+------+------+-------------------------------------------------+
1 row in set (0.09 sec)
mysql> explain select * from employees where  emp_no < 257654 or  hire_date = '1990-09-06';
+----+-------------+-----------+-------------+-------------------+-------------------+---------+------+--------+---------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+-------------+-------------------+-------------------+---------+------+--------+---------------------------------------------+
| 1 | SIMPLE | employees | index_merge | PRIMARY,inx_hi_dt | PRIMARY,inx_hi_dt | 4,3 | NULL | 149716 | Using union(PRIMARY,inx_hi_dt); Using where |
+----+-------------+-----------+-------------+-------------------+-------------------+---------+------+--------+---------------------------------------------+
1 row in set (0.00 sec)
mysql> desc select  birth_date  from  employees where birth_date ='1961-07-09' and hire_date ='1986-06-29';
+----+-------------+-----------+-------------+---------------------+---------------------+---------+------+------+----------------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+-------------+---------------------+---------------------+---------+------+------+----------------------------------------------------------------+
| 1 | SIMPLE | employees | index_merge | inx_hi_dt,idx_br_dt | idx_br_dt,inx_hi_dt | 3,3 | NULL | 1 | Using intersect(idx_br_dt,inx_hi_dt); Using where; Using index |
+----+-------------+-----------+-------------+---------------------+---------------------+---------+------+------+----------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> desc select  birth_date  from  employees where birth_date ='1961-07-09' or  hire_date ='1986-06-29';
+----+-------------+-----------+-------------+---------------------+---------------------+---------+------+------+-----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+-------------+---------------------+---------------------+---------+------+------+-----------------------------------------------+
| 1 | SIMPLE | employees | index_merge | inx_hi_dt,idx_br_dt | idx_br_dt,inx_hi_dt | 3,3 | NULL | 166 | Using union(idx_br_dt,inx_hi_dt); Using where |
+----+-------------+-----------+-------------+---------------------+---------------------+---------+------+------+-----------------------------------------------+
1 row in set (0.02 sec)
mysql> desc select  birth_date  from  employees where birth_date < '1950-07-09' or  hire_date < '1970-06-29';
+----+-------------+-----------+-------------+---------------------+---------------------+---------+------+------+----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+-------------+---------------------+---------------------+---------+------+------+----------------------------------------------------+
| 1 | SIMPLE | employees | index_merge | inx_hi_dt,idx_br_dt | idx_br_dt,inx_hi_dt | 3,3 | NULL | 2 | Using sort_union(idx_br_dt,inx_hi_dt); Using where |
+----+-------------+-----------+-------------+---------------------+---------------------+---------+------+------+----------------------------------------------------+
1 row in set (0.00 sec)
mysql> desc select  birth_date  from  employees where birth_date < '1950-07-09' or  hire_date = '1986-06-29';
+----+-------------+-----------+-------------+---------------------+---------------------+---------+------+------+----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+-------------+---------------------+---------------------+---------+------+------+----------------------------------------------------+
| 1 | SIMPLE | employees | index_merge | inx_hi_dt,idx_br_dt | idx_br_dt,inx_hi_dt | 3,3 | NULL | 111 | Using sort_union(idx_br_dt,inx_hi_dt); Using where |
+----+-------------+-----------+-------------+---------------------+---------------------+---------+------+------+----------------------------------------------------+
1 row in set (0.00 sec)

MySQL Index Merge Optimization的更多相关文章

  1. 8.2.1.4 Index Merge Optimization 索引合并优化:

    8.2.1.4 Index Merge Optimization 索引合并优化: 索引合并方法是用于检索记录 使用多个 范围扫描和合并它们的结果集到一起 mysql> show index fr ...

  2. MySQL index merge

    深入理解 index merge 是使用索引进行优化的重要基础之一. [ index merge]       当where谓词中存在多个条件(或者join)涉及到多个字段,它们之间进行 AND 或者 ...

  3. index merge的一次优化

    手机微博4040端口SQL优化 现象 某端口常态化延迟,通过使用pt-query-digest发现主要由于一条count(*)语句引发,具体如下: # .5s .58M rss, .84M vsz # ...

  4. MySQL 派生表(Derived Table) Merge Optimization

    本文将通过演示告诉你:MySQL中派生表(Derived Table)是什么?以及MySQL对它的优化. Background 有如下一张表: mysql> desc city; +------ ...

  5. MySQL 优化之 index merge(索引合并)

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

  6. MySQL 查询优化之 Index Merge

    MySQL 查询优化之 Index Merge Index Merge Intersection 访问算法 Index Merge Union 访问算法 Index Merge Sort-Union ...

  7. MySQL中Index Merge简介

    索引合并优化 官网翻译 MySQL5.7文档 索引合并是为了减少几个范围(type中的range类型:range can be used when a key column is compared t ...

  8. MySQL Index详解

    FROM:http://blog.csdn.net/tianmo2010/article/details/7930482 ①MySQL Index 一.SHOW INDEX会返回以下字段 1.Tabl ...

  9. Mysql Index、B Tree、B+ Tree、SQL Optimization

    catalog . 引言 . Mysql索引 . Mysql B/B+ Tree . Mysql SQL Optimization . MySQL Query Execution Process 1. ...

随机推荐

  1. dotnet core 自定义配置文件

    首先添加一个.json 文件,比如 setting.json 文件内容如下,记得把文件设置为“复制到输出目录” { "ConfigSetting": { "XXXName ...

  2. Java第二章----对象和类

    从第一章到第二章整整隔了一个月的时间,这速度也是慢的无语了.因为这个月负责开发公司一个SaaS类型APP,忙的昏天暗地终于上线了,这才有时间写个博客.本章还是以概念为主,有点枯燥重在理解. 第一节:对 ...

  3. IDEA第八章----远程调试

    大家有没有遇到相同分支的代码在本地就是没有问题的,但是到测试环境死活不能实现功能,且还不报错.通常我们的解决办法就是打日志,然后一点一点跟踪日志. 这时我们在想如果也可以按照本地一样能断点测试的程序就 ...

  4. ArcGis连接oracle失败:ORA-6413:连接未打开

    问题: 通过ARCMap 添加Oracle数据库连接时提示,ORA-6413:连接未打开. 运行环境: ArcGis 10.2 Oracle 10g 解决方法: 通过上网查找解决方法,网友说" ...

  5. docker with flannel

    ** 原创文章,请勿转载 ** docker的单host,多container环境下,是使用host的docker0网桥进行通信的.如果跨host, container之间要通信怎么办呢?答案是fla ...

  6. 【读书笔记】【深入理解ES6】#3-函数

    函数形参的默认值 ES6中的默认参数值 function makeRequest(url, timeout = 2000, callback = function() {}) { } 可以为任意参数指 ...

  7. 使用JPA中@Query 注解实现update 操作

    spring使用jpa进行update操作主要有两种方式: 1.调用保存实体的方法 1)保存一个实体:repository.save(T entity) 2)保存多个实体:repository.sav ...

  8. html页面的音频问题

    导火线 : 负责了项目中的话务间模块,处理音频出了一点问题 之前的处理 : //循环播放声音 var dialAudioDocument = document.createElement('audio ...

  9. html笔记2

    html css的用法 <style type="text/css">代表我要使用css了 <html> <head> <style ty ...

  10. 【转载】Java 内存分配全面浅析

    本文将由浅入深详细介绍Java内存分配的原理,以帮助新手更轻松的学习Java.这类文章网上有很多,但大多比较零碎.本文从认知过程角度出发,将带给读者一个系统的介绍. 本文转载自袭烽大神的博客,原文链接 ...