標籤:
索引合并最佳化官網翻譯
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,並且每一個組合都要下面的一種:
例如:
這個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,並且每一個組合都要下面的一種:
例如:
3. 通過sort_union演算法合并索引
這中演算法會在,使用or來排列條件,但是union演算法又不適用的情況
例如:
sort_union演算法和union演算法的不同之處在於:sort_union演算法在返回結果之前必須獲得所有行的行ID,並且將他們排序。
索引合并.md 參考:
[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]
MySQL中Index Merge簡介