mysql 索引合并_MySQL 索引合并(Index Merge)优化
本文問題
什么是Index Merge?Index Merge的限制有哪些?
如何查看語句是否使用了Index Merger?
Index Merge有哪幾種?分別適用于那些情景?
如何控制優化器是否使用Index Merge
Index Merge 索引合并
索引合并檢索方法可以檢索多個范圍掃描并將結果合并。這種訪問方法只能合并同一個表的索引掃描,不能合并跨表掃描。
合并可能生成基礎掃描結果的"并集","交集",或者"交集的并集"
示例:
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的已知缺陷
如果在WHERE語句中,存在多層嵌套的AND/OR,MySQL可能不會選擇最優的方案,可以嘗試通過拆分WHERE子句的條件來進行轉換:
(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 Merger不能應用于全文索引(fulltext index)
Index Merge的EXPLAIN輸出
type列的值顯示為index_merge
key列顯示使用的索引列表
key_len列顯示這些索引的最大長度(列表)。
Extra列顯示Index Merge的算法:
Using intersect(...)
Using union(...)
Using sort_union(...)
mysql> explain select * from test_merge where (col1<10 and col2>50) or col3=50;
+----+-------------+------------+------------+-------------+---------------+---------------+---------+------+------+----------+----------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------------+-------------+---------------+---------------+---------+------+------+----------+----------------------------------------------+
| 1 | SIMPLE | test_merge | NULL | index_merge | idx_1_2,idx_3 | idx_1_2,idx_3 | 5,5 | NULL | 214 | 100.00 | Using sort_union(idx_1_2,idx_3); Using where |
+----+-------------+------------+------------+-------------+---------------+---------------+---------+------+------+----------+----------------------------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> explain select * from test_merge where (col1=10 and col2=50) or col3=50;
+----+-------------+------------+------------+-------------+---------------+---------------+---------+------+------+----------+-----------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------------+-------------+---------------+---------------+---------+------+------+----------+-----------------------------------------+
| 1 | SIMPLE | test_merge | NULL | index_merge | idx_1_2,idx_3 | idx_1_2,idx_3 | 10,5 | NULL | 22 | 100.00 | Using union(idx_1_2,idx_3); Using where |
+----+-------------+------------+------------+-------------+---------------+---------------+---------+------+------+----------+-----------------------------------------+
1 row in set, 1 warning (0.00 sec)
Index Merge 算法
Index Merge Intersection 索引合并交集
這種方法適用于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;
索引合并交集算法在所有使用的索引上同時進行掃描,并從掃描結果中生成行的交集
如果查詢中的所有列都被使用的索引覆蓋,不需要檢索所有表行(EXPLAIN輸出中的Extra列中包括Using index)。例如這個語句:
SELECT COUNT(*) FROM t1 WHERE key1 = 1 AND key2 = 1;
如果使用的索引沒有覆蓋查詢中所有的行,只有當所有使用的索引的范圍條件滿足時才檢索整個行。
如果合并條件中包括Innodb表主鍵索引條件,主鍵并不用來檢索數據,而是用來篩選使用其他條件檢索出的行。 # 就是先通過其他的范圍條件篩選出一部分數據,在從這部分數據中,通過主鍵來篩選出最終的結果
Index Merge Union 索引合并并集
這種方法適用于WHERE子句中的條件是通過OR結合的不同索引的范圍條件時,其中的每個條件都需要滿足下列條件之一:
如果其中的索引是多列索引,條件中需要包括索引的所有列
key_part1 = const1 AND key_part2 = const2 ... AND key_partN = constN
在Innodb表的主鍵上的范圍條件
適用于Index Merger intersection算法的條件
示例:
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
這種方法適用于WHERE子句中的條件是通過OR結合的不同索引的范圍條件,但是不能使用Index Merge Union算法的情景
示例:
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并對行ID進行排序。
禁用Index Merge
在optimizer_swith中有4個關于Index Merge的變量:
index_merge,index_merge_intersection,index_merge_union,index_merge_sort_union
默認情況下都是啟用的。要單獨啟用某個算法,設置index_merge=off,并將相應的標志設置為on
問題答案
什么是Index Merge?Index Merge的限制有哪些?
如果查詢中使用到了不同的索引,可以對不同索引的條件分別進行范圍掃描,然后將掃描結果合并得到最終的結果,這就是Index Merge。
限制:只能合并同一個表的索引掃描結果,不能跨表合并。此外,無法對fulltext索引進行合并
如何查看語句是否使用了Index Merge?
EXPLAIN中type列的值為index_merge表示使用了索引合并。根據索引合并算法的不同,會在Extra列中顯示Using intersect/union/sort_union
Index Merge有哪幾種?分別適用于那些情景?
3種:Intersection,Union,Sort_union
Intersection:使用AND結合的關于不同索引的條件(普通索引的等值表達式或者主鍵索引的范圍表達式)
Union和Sort Union:使用OR結合的關于不同索引的范圍條件
區別:當條件為普通索引的等值表達式或者主鍵索引的范圍表達式時,可以使用Union。其他不符合條件的只能使用Sort Union
如果包括多列索引,在范圍條件中需要包括索引中的所有列。
如何控制優化器是否使用Index Merge
在optimizer_swith中有4個關于Index Merge的變量:
index_merge,index_merge_intersection,index_merge_union,index_merge_sort_union
默認情況下都是啟用的。要單獨啟用某個算法,設置index_merge=off,并將相應的標志設置為on
總結
以上是生活随笔為你收集整理的mysql 索引合并_MySQL 索引合并(Index Merge)优化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: xpress-mp优化实例精选_量化研究
- 下一篇: oracle 从右往左截取_截取GIF、