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. ...
随机推荐
- MicroPython最全资料集锦丨TPYBoard全系列教程之文档+例程源码
MicroPython成功将Python引入到嵌入式领域,近几年MicroPython的发展和普及也证明,Python无疑将在未来几年内快速抢占和蚕食C/C++的份额.包括现在比较火爆的机器人.无人机 ...
- 固定底部导航菜单-续集(BottomMenu-移动端V3.0)
固定底部导航菜单-续集(BottomMenu-移动端V3.0) 适应在客户端,点击弹出二级菜单.因为手机不支持hover.所以使用click点击实现弹出菜单,并且一级菜单聚焦变色,变化背景图片 核心c ...
- winform listview用法
资源收集 C#winform中ListView的使用 C# WinForm开发系列 - ListBox/ListView/Panel(介绍了一些listview的高级用法) 直接上代码 示例一: th ...
- python 命令
pip list 可以查看已经安装的插件 pip show name 可以查看插件的信息(如:pip show selenium) pip install selenium==[version num ...
- Core Animation文档翻译 (第一篇)
Core Animation 文档翻译(第一篇) 前言 作为iOS 开发,官方文档的阅读是很有必要的,值此周末便写下此文.作为iOS 实际经验3年的开发,之前有阅读并实践过经典的<iOS核心动画 ...
- install brew cask
os x install brew cask '/usr/../../brew-cask.rb' does not exist brew 已安装完毕,安装brew cask brew install ...
- 设备树的interrupt
http://www.cnblogs.com/targethero/p/5080499.html https://www.cnblogs.com/xiaojiang1025/p/6131381.htm ...
- 使用quartz实现不重启服务器修改自定义配置
为了方便维护系统,开发中通常会设置一些自定义参数,写在单独的配置文件里,需要调整时可直接登录服务器修复配置文件,而不需要修改程序.但尴尬的是,web服务器并不会自动重新加载配置文件,重启服务器又会中断 ...
- ajax中url赋json格式的值时发生中文乱码的相关问题
具体流程:转入到jsp界面时会加载ajax,ajax转到url时传带hide在jsp界面的值titleString,其来源见下面的代码. String title=new String("\ ...
- 我使用 Docker 部署 Celery 遇到的问题
问题1 - Sending due task 本机测试时没有问题的,但是在线上 docker 中,任务一直显示 "Sending due task".超时的任务是 Django O ...