MySQL Index Merge Optimization
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(...)
(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的更多相关文章
- 8.2.1.4 Index Merge Optimization 索引合并优化:
8.2.1.4 Index Merge Optimization 索引合并优化: 索引合并方法是用于检索记录 使用多个 范围扫描和合并它们的结果集到一起 mysql> show index fr ...
- MySQL index merge
深入理解 index merge 是使用索引进行优化的重要基础之一. [ index merge] 当where谓词中存在多个条件(或者join)涉及到多个字段,它们之间进行 AND 或者 ...
- index merge的一次优化
手机微博4040端口SQL优化 现象 某端口常态化延迟,通过使用pt-query-digest发现主要由于一条count(*)语句引发,具体如下: # .5s .58M rss, .84M vsz # ...
- MySQL 派生表(Derived Table) Merge Optimization
本文将通过演示告诉你:MySQL中派生表(Derived Table)是什么?以及MySQL对它的优化. Background 有如下一张表: mysql> desc city; +------ ...
- MySQL 优化之 index merge(索引合并)
深入理解 index merge 是使用索引进行优化的重要基础之一.理解了 index merge 技术,我们才知道应该如何在表上建立索引. 1. 为什么会有index merge 我们的 where ...
- MySQL 查询优化之 Index Merge
MySQL 查询优化之 Index Merge Index Merge Intersection 访问算法 Index Merge Union 访问算法 Index Merge Sort-Union ...
- MySQL中Index Merge简介
索引合并优化 官网翻译 MySQL5.7文档 索引合并是为了减少几个范围(type中的range类型:range can be used when a key column is compared t ...
- MySQL Index详解
FROM:http://blog.csdn.net/tianmo2010/article/details/7930482 ①MySQL Index 一.SHOW INDEX会返回以下字段 1.Tabl ...
- Mysql Index、B Tree、B+ Tree、SQL Optimization
catalog . 引言 . Mysql索引 . Mysql B/B+ Tree . Mysql SQL Optimization . MySQL Query Execution Process 1. ...
随机推荐
- WebRTC 入门到放弃(一)WebRTC
前言 WebRTC,名称源自网页实时通信(Web Real-Time Communication)的缩写,是一个支持网页浏览器进行实时语音对话或视频对话的技术,是谷歌2010年以6820万美元收购Gl ...
- H5 + 开发App(分享功能)
我们开发App有一个不可少的功能,就是分享功能.让用户将app分享到他的社交圈.比如微信 QQ 微博等等. 准备工作:我们要先去申请相关的权限, 这是传送门http://ask.dcloud.net. ...
- 《algorithms Unlocked》读书笔记3——计数排序
<Algorithms Unlocked>是 <算法导论>的合著者之一 Thomas H. Cormen 写的一本算法基础,算是啃CLRS前的开胃菜和辅助教材.如果CLRS的厚 ...
- CentOS7下安装Docker-Compose
Docker-Compose是一个部署多个容器的简单但是非常必要的工具. 安装Docker-Compose之前,请先安装 python-pip 安装 python-pip 1.首先检查linux有没有 ...
- eclipse从git拉去出现红色方块的解决办法
1:由于错误已经解决,这里借了一副图,主要是显示这个红色方块,然后贴一下解决方法,日后好脑补: 大家一看肯定都是冲突了,我也是第一次遇到这种错误,贴一下(鼠标右击项目找到如下的Reset): 然后红色 ...
- Mac 下 android/iOS https抓包
一.Charles简介 Charles,是用Java开发的,所以跨平台,不仅可以在Mac上使用,Linux以及Window下都是可以使用的,当然需要安装JDK,才能运行,但目前是收费的. 二.下载 官 ...
- 【RMQ】洛谷P3379 RMQ求LCA
题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...
- 常用Atom插件列表
1.simplified-chinese-menu Atom的简体中文语言包,完整汉化,兼容所有已发布的版本Atom. 2.tree-view-finder 左边菜单栏显示方式,类似Mac OS下的f ...
- 一个Flask运行分析
当我们安装好Flask环境之后,创建好项目,就会自动生成下面这段代码: from flask import Flask app = Flask(__name__) @app.route('/') de ...
- 第一个程序python.py
print("hello word")print("hello hello")print("hello hello")print(" ...