- 7.2.6.1. 索引合并交集訪問算法
- 7.2.6.2. 索引合并并集訪問算法
- 7.2.6.3. 索引合并排序并集訪問算法
索引合并方法用于通過range掃描搜索行并將結果合成一個。合并會產生并集、交集或者正在進行的掃描的交集的并集。
在EXPLAIN輸出中,該方法表現為type列內的index_merge。在這種情況下,key列包含一列使用的索引,key_len包含這些索引的最長的關鍵元素。
例如:
SELECT * FROM tbl_name WHERE key_part1 = 10 OR key_part2 = 20;
SELECT * FROM tbl_name
WHERE (key_part1 = 10 OR key_part2 = 20) AND non_key_part=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);
索引合并方法有幾種訪問算法 (參見EXPLAIN輸出的Extra字段):
· 交集
· 聯合
· 排序并集
后面幾節更加詳細地描述了這些方法。
注釋:索引合并優化算法具有以下幾個已知缺陷:
· 如果可以對某些關鍵字進行范圍掃描,則不考慮索引合并。例如,下面的查詢:
· SELECT * FROM t1 WHERE (goodkey1 < 10 OR goodkey2 < 20) AND badkey < 30;
對于該查詢,可以有兩個方案:
1. 使用(goodkey1 < 10 OR goodkey2 < 20)條件進行索引合并掃描。
2. 使用badkey < 30條件進行范圍掃描。
然而,優化器只考慮第2個方案。如果這不是你想要的,你可以通過使用IGNORE INDEX或FORCE INDEX讓優化器考慮index_merge。下面的查詢使用索引合并執行:
SELECT * FROM t1 FORCE INDEX(goodkey1,goodkey2)
WHERE (goodkey1 < 10 OR goodkey2 < 20) AND badkey < 30;
SELECT * FROM t1 IGNORE INDEX(badkey)
WHERE (goodkey1 < 10 OR goodkey2 < 20) AND badkey < 30;
· 如果查詢有一個復雜的WHERE子句,有較深的AND/OR嵌套關系,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)
index_merge訪問方法的不同變量之間的選擇和其它訪問方法基于各適用選項的成本估計。