索引合并优化

官网翻译

MySQL5.7文档 索引合并是为了减少几个范围(type中的range类型:range can be used when a key column is compared to a constant using any of the =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, or IN() operators:)扫描的行数,并将他们的结果合并成一个。这里的合并可能是, 他们的并集、交集或者几个交集后的并集。这种索引的合并只能合并一个表中的索引扫描;而不能合并 多个表种的范围扫描。

在explain的输出中,索引合并将会在type列出现,显示为index merge。在这种case中,key列包含合并的索引的 一个列表,并且key_len列包含这些索引中最长的key的部分。

例如:

索引合并方法有几种合并算法(见explain输出的extra列)

  • Using intersect(...)
  • Using union(...)
  • Using sort_union(...)

下面的小节会更详细的介绍这些算法。

注意

索引合并算法有以下已知的缺陷

如果你的查询使用的是一个带有多层and/or嵌套的复杂where子句, MySQL就不会选择这个优化策略了,你可以尝试使用一下规则来拆分他们:

索引合并还不能应用到全文检索上。但未来的MySQL版本可能会支持

具体是使用索引合并优化,还是其他的优化方法?MySQL要根据他的代价估算模型来决定。

1. 通过Intersection算法合并索引

这个算法会被使用,当where子句可以被转换为几个排列情况,使用and来组合不同的key,并且每一个组合都要下面的一种:

  • 在这种形式中,索引要有确切的N部分(即,所有的索引列都要覆盖)

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

  • InnoDB表中主键的任何范围条件

例如:

这个Intersection合并索引算法会同时扫描所有使用索引,并产出:(合并的索引)(所扫描的行序列)的交集。

如果要查询的所有的列都在被合并的索引上,就不会扫描表中的所有列了(即被索引覆盖了,在explain的输出 中在extra列就会显示Using index)。下面是一个例子:

如果使用的索引没有覆盖所有的查询列,就会根据具体条件回表查询全部的数据行列了。

If one of the merged conditions is a condition over a primary key of an InnoDB table, it is not used for row retrieval, but is used to filter out rows retrieved using other conditions.

2. 通过Union算法合并索引

这个算法的使用条件和Intersection算法差不多。这个算法使用到,where子句可以别转换为使用or来组合 不同的key,并且每一个组合都要下面的一种:

  • 在这种形式中,索引要有确切的N部分(即,所有的索引列都要覆盖)

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

  • InnoDB表中主键的任何范围条件

  • 索引合并的intersect算法能使用的情况也行

例如:

3. 通过sort_union算法合并索引

这中算法会在,使用or来排列条件,但是union算法又不适用的情况

例如:

sort_union算法和union算法的不同之处在于:sort_union算法在返回结果之前必须获得所有行的行ID,并且将他们排序。

 参考:

[1]:[http://www.tuicool.com/articles/eyURR3r]
[2]:[http://www.orczhou.com/index.php/2013/01/mysql-source-code-query-optimization-index-merge/]
[3]:[http://dev.mysql.com/doc/refman/5.7/en/index-merge-optimization.html]

最新文章

  1. 【LeetCode】#7 Reverse Integer
  2. 使用Diagnose服务查看Azure网站诊断信息
  3. OKhttp的封装(下)
  4. 【XLL API 函数】xlCoerce
  5. Bitmap.Config 详解
  6. winform INI文件操作辅助类
  7. VSTO学习笔记(五)批量编辑Excel 2010 x64
  8. Citrix 服务器虚拟化之一 网络部署Xenserver 6.2
  9. Struts2 02--通配符
  10. 用redis的scan命令代替keys命令,以及在spring-data-redis中遇到的问题
  11. 阅读ug949-vivado-design-methodology笔记
  12. js中的原型
  13. 英语口语练习系列-C31-图书-谈论事物-白雪歌送武判官归京
  14. Queue depth
  15. PAT Rational Sum
  16. java struts2 的 文件下载
  17. 2115: [Wc2011] Xor
  18. JSON数据填充表格——(三)
  19. PHP实现的多文件上传类及用法示例
  20. Python 日志模块的定制

热门文章

  1. python ndarray相关操作:转置、翻转
  2. 详解php中空字符串和0之间的关系
  3. Ubuntu无法连接无线网
  4. 遗传算法MATLAB实现(2):一元函数优化举例
  5. 可变参数与foreach 的原理
  6. python 源文件编码
  7. C++继承与构造函数、复制控制
  8. How to use AutoMapper
  9. Pytorch的网络结构可视化(tensorboardX)(详细)
  10. 亿级消息系统的核心存储:Tablestore发布Timeline 2.0模型