6.MySQL優化索引合併優化
介紹
索引合併訪問方法檢索具有多個範圍掃描的行併合並其結果合而為一。 此訪問方法僅合併來自單個表的索引掃描,而不是跨多個掃描表。 合併可以生成其基礎掃描的聯合,交叉或交叉聯合。
下面舉個例子介紹一下如何使用:
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);
索引合併優化演算法具有以下已知限制:
-
如果您的查詢具有帶有深AND/OR巢狀的複雜WHERE子句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)
-
索引合併不適用於全文索引。
在EXPLAIN輸出中,索引合併方法在型別列中顯示為index_merge。 在這種情況下,鍵列包含使用的索引列表,key_len包含最長鍵的列表
這些索引的部分。
Index Merge訪問方法有幾種演算法,它們顯示在EXPLAIN輸出的Extra欄位中:
- Using intersect(…)
- Using union(…)
- Using sort_union(…)
以下部分更詳細地描述了這些演算法。 優化器根據各種可用選項的成本估算在不同的可能索引合併演算法和其他訪問方法之間進行選擇。
- Index Merge Intersection Access Algorithm
- Index Merge Union Access Algorithm
- Index Merge Sort-Union Access Algorithm
- Influencing Index Merge Optimization
1 Index Merge Intersection Access Algorithm
-
當WHERE子句在與AND組合的不同鍵上轉換為多個範圍條件時,此訪問演算法適用,並且每個條件都是以下之一:
key_part1 = const1 AND key_part2 = const2 ... AND key_partN = constN
-
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 Access Algorithm的意思就是對所有使用的索引進行同時掃描(simultaneous scans),並生成從合併索引掃描接收的行序列的交集。
其實就是在掃描索引的時候就對索引集合進行了合併減少了取資料的數量。
2 Index Merge Union Access Algorithm
該演算法的標準與Index Merge Intersection Access Algorithm的標準類似。當表的WHERE子句在與OR結合的不同鍵上轉換為多個範圍條件時,該演算法適用。
-
這種形式的N部分表示式,其中索引具有正好N個部分(即,所有索引部分都被覆蓋),並且每個條件都是以下之一:
key_part1 = const1 AND key_part2 = const2 ... AND key_partN = constN
-
InnoDB表的主鍵上的任何範圍條件。
例如:
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;
3 Index Merge Sort-Union Access Algorithm
當WHERE子句轉換為OR組合的多個範圍條件時,此訪問演算法適用,但是Index Merge union 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演算法和union演算法之間的區別在於sort-union演算法必須首先獲取所有行的行ID,然後在返回任何行之前對它們進行排序。
4 Influencing Index Merge Optimization
索引合併的使用取決於optimizer_switch系統變數的index_merge,index_merge_intersection,index_merge_union和index_merge_sort_union標誌的值。預設情況下,所有這些標誌都已開啟。 要僅啟用某些演算法,請將index_merge設定為off,並僅啟用應允許的其他演算法。
除了使用optimizer_switch系統變數來控制會話範圍內的索引合併演算法的優化器使用之外,MySQL還支援優化器提示以在持久化基礎上影響優化器。