最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL使用索引合并(Index?Merge)提高查詢(xún)效率

 更新時(shí)間:2024年07月13日 10:43:29   作者:華為云開(kāi)發(fā)者聯(lián)盟  
本文介紹了索引合并(Index?Merge)的實(shí)現(xiàn)原理、場(chǎng)景約束與通過(guò)案例驗(yàn)證的優(yōu)缺點(diǎn),在實(shí)際使用中,當(dāng)查詢(xún)條件列較多且無(wú)法使用聯(lián)合索引時(shí),就可以考慮使用索引合并,利用多個(gè)索引加速查詢(xún),但要注意,索引合并并非在任何場(chǎng)景下均具有較好的效果,需要結(jié)合具體情況選擇

在生產(chǎn)環(huán)境中,MySQL語(yǔ)句的where查詢(xún)通常會(huì)包含多個(gè)條件判斷,以AND或OR操作進(jìn)行連接。然而,對(duì)一個(gè)表進(jìn)行查詢(xún)最多只能利用該表上的一個(gè)索引,其他條件需要在回表查詢(xún)時(shí)進(jìn)行判斷(不考慮覆蓋索引的情況)。當(dāng)回表的記錄數(shù)很多時(shí),需要進(jìn)行大量的隨機(jī)IO,這可能導(dǎo)致查詢(xún)性能下降。因此,MySQL 5.x 版本推出索引合并(Index Merge)來(lái)解決該問(wèn)題。

本文將基于MySQL 8.0.22版本對(duì)MySQL的索引合并功能、實(shí)現(xiàn)原理及場(chǎng)景約束進(jìn)行詳細(xì)介紹,同時(shí)也會(huì)結(jié)合原理對(duì)其優(yōu)缺點(diǎn)進(jìn)行淺析,并通過(guò)例子進(jìn)行驗(yàn)證。

什么是索引合并(Index Merge)?

索引合并是通過(guò)對(duì)一個(gè)表同時(shí)使用多個(gè)索引進(jìn)行條件掃描,并將滿(mǎn)足條件的多個(gè)主鍵集合取交集或并集后再進(jìn)行回表,可以提升查詢(xún)效率。

索引合并主要包含交集(intersection),并集(union)和排序并集(sort-union)三種類(lèi)型:

  • intersection:將基于多個(gè)索引掃描的結(jié)果集取交集后返回給用戶(hù);
  • union:將基于多個(gè)索引掃描的結(jié)果集取并集后返回給用戶(hù);
  • sort-union:與union類(lèi)似,不同的是sort-union會(huì)對(duì)結(jié)果集進(jìn)行排序,隨后再返回給用戶(hù);

MySQL中有四個(gè)開(kāi)關(guān)(index_merge、index_merge_intersection、index_merge_union以及index_merge_sort_union)對(duì)上述三種索引合并類(lèi)型提供支持,可以通過(guò)修改optimizer_switch系統(tǒng)參數(shù)中的四個(gè)開(kāi)關(guān)標(biāo)識(shí)來(lái)控制索引合并特性的使用。

假設(shè)創(chuàng)建表T,并插入如下數(shù)據(jù):

CREATE TABLE T(  `id` int NOT NULL AUTO_INCREMENT,
`a` int NOT NULL,
`b` char(1) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_a` (`a`) USING BTREE,
KEY `idx_b` (`b`) USING BTREE
)ENGINE=InnoDB AUTO_INCREMENT=1;

INSERT INTO T (a, b) VALUES (1, 'A'), (2, 'B'),(3, 'C'),(4, 'B'),(1, 'C');

默認(rèn)情況下,四個(gè)開(kāi)關(guān)均為開(kāi)啟狀態(tài)。如果需要單獨(dú)使用某個(gè)合并類(lèi)型,需設(shè)置index_merge=off,并將相應(yīng)待啟用的合并類(lèi)型標(biāo)識(shí)(例如,index_merge_sort_union)設(shè)置為on。

開(kāi)關(guān)開(kāi)啟后,可通過(guò)EXPLAIN執(zhí)行計(jì)劃查看當(dāng)前查詢(xún)語(yǔ)句是否使用了索引合并。

mysql> explain SELECT * FROM T WHERE a=1 OR b='B';
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+---------------------------------------+
| id | select_type | table | partitions | type        | possible_keys | key         | key_len | ref  | rows | filtered | Extra                                 
|+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+---------------------------------------+
|  1 | SIMPLE      | T     | NULL       | index_merge | idx_a,idx_b   | idx_a,idx_b | 4,5     | NULL |    4 |   100.00 | Using union(idx_a,idx_b); Using where |
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+---------------------------------------+
1 row in set, 1 warning (0.01 sec)

上面代碼顯示type類(lèi)型為index_merge,表示使用了索引合并。key列顯示使用到的所有索引名稱(chēng),該語(yǔ)句中同時(shí)使用了idx_a和idx_b兩個(gè)索引完成查詢(xún)。Extra列顯示具體使用了哪種類(lèi)型的索引合并,該語(yǔ)句顯示Using union(...),表示索引合并類(lèi)型為union。

此外,可以使用index_merge/no_index_merge給查詢(xún)語(yǔ)句添加hint,強(qiáng)制SQL語(yǔ)句使用/不使用索引合并。

• 如果查詢(xún)默認(rèn)未使用索引合并,可以通過(guò)添加index_merge強(qiáng)制指定:

mysql> EXPLAIN SELECT * FROM T WHERE a=2 AND b='A';
+----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key   | key_len | ref   | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | T     | NULL       | ref  | idx_a,idx_b   | idx_a | 4       | const |    1 |    20.00 | Using where |
+----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
mysql> EXPLAIN SELECT /*+ INDEX_MERGE(T idx_a,idx_b) */ * FROM T WHERE a=2 AND b='A';
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+--------------------------------------------------------+
| id | select_type | table | partitions | type        | possible_keys | key         | key_len | ref  | rows | filtered | Extra                                                  |
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+--------------------------------------------------------+
|  1 | SIMPLE      | T     | NULL       | index_merge | idx_a,idx_b   | idx_a,idx_b | 4,5     | NULL |    1 |   100.00 | Using intersect(idx_a,idx_b); Using where; Using index |
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+--------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)

• 使用no_index_merge給查詢(xún)語(yǔ)句添加hint,可以忽略索引合并優(yōu)化:

mysql> EXPLAIN SELECT * FROM T WHERE a=1 OR b='A';
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+---------------------------------------+
| id | select_type | table | partitions | type        | possible_keys | key         | key_len | ref  | rows | filtered | Extra                                 |
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+---------------------------------------+
|  1 | SIMPLE      | T     | NULL       | index_merge | idx_a,idx_b   | idx_a,idx_b | 4,5     | NULL |    3 |   100.00 | Using union(idx_a,idx_b); Using where |
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+---------------------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> EXPLAIN SELECT /*+ NO_INDEX_MERGE(T idx_a,idx_b) */ * FROM T WHERE a=1 OR b='A';
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | T     | NULL       | ALL  | idx_a,idx_b   | NULL | NULL    | NULL |    5 |    36.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

索引合并(Index Merge)原理

1.  Index Merge Intersection

Index Merge Intersection會(huì)在使用到的多個(gè)索引上同時(shí)進(jìn)行掃描,并取這些掃描結(jié)果的交集作為最終結(jié)果集。

以“SELECT * FROM T WHERE a=1 AND b='C'; ”語(yǔ)句為例:

• 未使用索引合并時(shí),MySQL利用索引idx_a獲取到滿(mǎn)足條件a=1的所有主鍵id,根據(jù)主鍵id進(jìn)行回表查詢(xún)到相關(guān)記錄,隨后再使用條件b='C'對(duì)這些記錄進(jìn)行判斷,獲取最終查詢(xún)結(jié)果。

mysql> explain SELECT /*+ NO_INDEX_MERGE(T idx_a,idx_b) */ * FROM T WHERE a=1 AND b='C';
+----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key   | key_len | ref   | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | T     | NULL       | ref  | idx_a,idx_b   | idx_a | 4       | const |    2 |    40.00 | Using where |
+----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

• 使用索引合并時(shí),MySQL分別利用索引idx_a和idx_b獲取滿(mǎn)足條件a=1和b='C'的主鍵id集合setA和setB。隨后取setA和setB中主鍵id的交集setC,并使用setC中主鍵id進(jìn)行回表,獲取最終查詢(xún)結(jié)果。

mysql> explain SELECT * FROM T WHERE a=1 AND b='C';
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+--------------------------------------------------------+
| id | select_type | table | partitions | type        | possible_keys | key         | key_len | ref  | rows | filtered | Extra                                                  |
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+--------------------------------------------------------+
|  1 | SIMPLE      | T     | NULL       | index_merge | idx_a,idx_b   | idx_a,idx_b | 4,5     | NULL |    1 |   100.00 | Using intersect(idx_a,idx_b); Using where; Using index |
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+--------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)

執(zhí)行流程如下:

MySQL中為什么要使用索引合并(Index Merge)?_索引合并

圖1  SELECT * FROM T WHERE a=1 AND b='C';執(zhí)行流程

2. Index Merge Union

Index Merge Union會(huì)在使用到的多個(gè)索引上同時(shí)進(jìn)行掃描,并取這些掃描結(jié)果的并集作為最終結(jié)果集。

以“SELECT * FROM T WHERE a=1 OR b='B'; ”語(yǔ)句為例:

• 未使用索引合并時(shí),MySQL通過(guò)全表掃描獲取所有記錄信息,隨后再使用條件a=1和b='B'對(duì)這些記錄進(jìn)行判斷,獲取最終查詢(xún)結(jié)果。

mysql> EXPLAIN SELECT /*+ NO_INDEX_MERGE(T idx_a,idx_b) */ * FROM T WHERE a=1 OR b='B';
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | T     | NULL       | ALL  | idx_a,idx_b   | NULL | NULL    | NULL |    5 |    50.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

• 使用索引合并算法時(shí),MySQL分別利用索引idx_a和idx_b獲取滿(mǎn)足條件a=1和b='B'的主鍵id集合setA和setB。隨后,取setA和setB中主鍵id的并集setC,并使用setC中主鍵id進(jìn)行回表,獲取最終查詢(xún)結(jié)果。

mysql> EXPLAIN SELECT * FROM T WHERE a=1 OR b='B';
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+---------------------------------------+
| id | select_type | table | partitions | type        | possible_keys | key         | key_len | ref  | rows | filtered | Extra                                 |
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+---------------------------------------+
|  1 | SIMPLE      | T     | NULL       | index_merge | idx_a,idx_b   | idx_a,idx_b | 4,5     | NULL |    4 |   100.00 | Using union(idx_a,idx_b); Using where |
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+---------------------------------------+
1 row in set, 1 warning (0.01 sec)

執(zhí)行流程如下:

MySQL中為什么要使用索引合并(Index Merge)

圖2  SELECT * FROM T WHERE a=1 OR b='B';執(zhí)行流程

3. Index Merge Sort-Union

Sort-Union索引合并與Union索引合并原理相似,只是比單純的Union索引合并多了一步對(duì)二級(jí)索引記錄的主鍵id排序的過(guò)程。由OR連接的多個(gè)范圍查詢(xún)條件組成的WHERE子句不滿(mǎn)足Union算法時(shí),優(yōu)化器會(huì)考慮使用Sort-Union算法。例如:

mysql> EXPLAIN SELECT * FROM T WHERE a<3 OR b<'B';
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+--------------------------------------------+
| id | select_type | table | partitions | type        | possible_keys | key         | key_len | ref  | rows | filtered | Extra                                      |
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+--------------------------------------------+
|  1 | SIMPLE      | T     | NULL       | index_merge | idx_a,idx_b   | idx_a,idx_b | 4,5     | NULL |    4 |   100.00 | Using sort_union(idx_a,idx_b); Using where |
+----+-------------+-------+------------+-------------+---------------+-------------+---------+------+------+----------+--------------------------------------------+
1 row in set, 1 warning (0.00 sec)

應(yīng)用場(chǎng)景約束

1. 總體約束

• Index Merge不能應(yīng)用于全文索引(Fulltext Index)。

• Index Merge只能合并同一個(gè)表的索引掃描結(jié)果,不能跨表合并。

以上約束適用于Intersection,Union和Sort-Union三種合并類(lèi)型。此外,Intersection和Union存在特殊的場(chǎng)景約束。

2. Index Merge Intersection

使用Intersection要求AND連接的每個(gè)條件必須是如下形式之一:

(1) 當(dāng)索引包含多個(gè)列時(shí),每個(gè)列都必須被如下等值條件覆蓋,不允許出現(xiàn)范圍查詢(xún)。若使用索引為聯(lián)合索引時(shí),每個(gè)列都必須等值匹配,不能出現(xiàn)只匹配部分列的情況。

key_par1 = const1 AND key_par2 = const2 ... AND key_partN = constN

(2) 若過(guò)濾條件中存在主鍵列,主鍵列可以進(jìn)行范圍匹配。

mysql> EXPLAIN SELECT * FROM T WHERE id<3 AND b='A';
+----+-------------+-------+------------+-------------+---------------+---------------+---------+------+------+----------+---------------------------------------------+
| id | select_type | table | partitions | type        | possible_keys | key           | key_len | ref  | rows | filtered | Extra                                       |
+----+-------------+-------+------------+-------------+---------------+---------------+---------+------+------+----------+---------------------------------------------+
|  1 | SIMPLE      | T     | NULL       | index_merge | PRIMARY,idx_b | idx_b,PRIMARY | 9,4     | NULL |    1 |   100.00 | Using intersect(idx_b,PRIMARY); Using where |
+----+-------------+-------+------------+-------------+---------------+---------------+---------+------+------+----------+---------------------------------------------+
1 row in set, 1 warning (0.00 sec)

上述的要求,本質(zhì)上是為了確保索引取出的記錄是按照主鍵id有序排列的,因?yàn)镮ndex Merge Intersection對(duì)兩個(gè)有序集合取交集更簡(jiǎn)單。同時(shí),主鍵有序的情況下,回表將不再是單純的隨機(jī)IO,回表的效率也會(huì)更高。

3. Index Merge Union

使用Union要求OR連接的每個(gè)條件,必須是如下形式之一:

(1) 當(dāng)索引包含多個(gè)列時(shí),則每個(gè)列都必須被如下等值條件覆蓋,不允許出現(xiàn)范圍查詢(xún)。若使用索引為聯(lián)合索引時(shí),在聯(lián)合索引中的每個(gè)列都必須等值匹配,不能出現(xiàn)只匹配部分列的情況。

key_par1 = const1 OR key_par2 = const2 ... OR key_partN = constN

(2) 若過(guò)濾條件中存在主鍵列,主鍵列可以進(jìn)行范圍匹配。

mysql> EXPLAIN SELECT * FROM T WHERE id>3 OR b='A';
+----+-------------+-------+------------+-------------+---------------+---------------+---------+------+------+----------+-----------------------------------------+
| id | select_type | table | partitions | type        | possible_keys | key           | key_len | ref  | rows | filtered | Extra                                   |
+----+-------------+-------+------------+-------------+---------------+---------------+---------+------+------+----------+-----------------------------------------+
|  1 | SIMPLE      | T     | NULL       | index_merge | PRIMARY,idx_b | PRIMARY,idx_b | 4,5     | NULL |    3 |   100.00 | Using union(PRIMARY,idx_b); Using where |
+----+-------------+-------+------------+-------------+---------------+---------------+---------+------+------+----------+-----------------------------------------+
1 row in set, 1 warning (0.00 sec)

Index Merge的優(yōu)缺點(diǎn)

• Index Merge Intersection在使用到的多個(gè)索引上同時(shí)進(jìn)行掃描,并取這些掃描結(jié)果的并集作為最終結(jié)果集。

當(dāng)優(yōu)化器根據(jù)搜索條件從某個(gè)索引中獲取的記錄數(shù)極多時(shí),適合使用Intersection對(duì)取交集后的主鍵id以順序I/O進(jìn)行回表,其開(kāi)銷(xiāo)遠(yuǎn)小于使用隨機(jī)IO進(jìn)行回表。反之,當(dāng)根據(jù)搜索條件掃描出的記錄極少時(shí),因?yàn)樾枰嘁徊胶喜⒉僮?,Intersection反而不占優(yōu)勢(shì)。在8.0.22版本,對(duì)于AND連接的點(diǎn)查場(chǎng)景,通過(guò)建立聯(lián)合索引可以更好的減少回表。

• Index Merge Union在使用到的多個(gè)索引上同時(shí)進(jìn)行掃描,并取這些掃描結(jié)果的并集作為最終結(jié)果集。

當(dāng)優(yōu)化器根據(jù)搜索條件從某個(gè)索引中獲取的記錄數(shù)比較少,通過(guò)Union索引合并后進(jìn)行訪(fǎng)問(wèn)的代價(jià)比全表掃描更小時(shí),使用Union的效果才會(huì)更優(yōu)。

• Index Merge Sort-Union比單純的Union索引合并多了一步對(duì)索引記錄的主鍵id排序的過(guò)程。

當(dāng)優(yōu)化器根據(jù)搜索條件從某個(gè)索引中獲取的記錄數(shù)比較少的時(shí),對(duì)這些索引記錄的主鍵id進(jìn)行排序的成本不高,此時(shí)可以加速查詢(xún)。反之,當(dāng)需要排序的記錄過(guò)多時(shí),該算法的查詢(xún)效率不一定更優(yōu)。

我們以Index Merge Union為例,對(duì)上述分析進(jìn)行驗(yàn)證。

1. 場(chǎng)景構(gòu)造

# 創(chuàng)建表CREATE TABLE T(  `id` int NOT NULL AUTO_INCREMENT,
`a` int NOT NULL,`
b` char(1) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_a` (`a`) USING BTREE,
KEY `idx_b` (`b`) USING BTREE
)ENGINE=InnoDB AUTO_INCREMENT=1;

# 插入數(shù)據(jù)
DELIMITER $$
CREATE PROCEDURE insertT()
BEGIN
DECLARE i INT DEFAULT 0;
START TRANSACTION;
WHILE i<=100000 do
if (i%100 = 0) then
INSERT INTO T (a, b) VALUES (10,CHAR(rand()*(90-65)+65));
else
INSERT INTO T (a, b) VALUES (i,CHAR(rand()*(90-65)+65));
end if;
SET i=i+1;
END WHILE;
COMMIT;
END$$
DELIMITER ;
call insertT();

# 執(zhí)行測(cè)試語(yǔ)句
SQL1: SELECT * FROM T WHERE a=101 OR b='A';
SQL2: SELECT /*+ NO_INDEX_MERGE(T idx_a,idx_b) */ * FROM T WHERE a=101 OR b='A';
SQL3: SELECT * FROM T WHERE a=10 OR b='A';
SQL4: SELECT /*+ NO_INDEX_MERGE(T idx_a,idx_b) */ * FROM T WHERE a=10 OR b='A';

2. 執(zhí)行結(jié)果及分析

每條語(yǔ)句查詢(xún)5次,去掉最大值和最小值,取剩余三次結(jié)果平均值。4條語(yǔ)句查詢(xún)結(jié)果如下:

測(cè)試語(yǔ)句

第一次查詢(xún)/ms

第二次查詢(xún)/ms

第三次查詢(xún)/ms

第四次查詢(xún)/ms

第五次查詢(xún)/ms

平均值/ms

SQL1

5.481

5.422

5.117

4.892

5.426

5.322

SQL2

31.129

32.645

30.943

31.142

32.625

31.632

SQL3

7.872

7.200

7.824

7.955

7.949

7.882

SQL4

31.139

33.318

31.476

31.645

31.27

31.464

對(duì)比使用索引合并的SQL1和未使用索引合并的SQL2的查詢(xún)結(jié)果可知,使用索引合并的SQL1具有更高的查詢(xún)效率,這點(diǎn)從語(yǔ)句的explain analyze分析中也可以看出:

使用索引合并的SQL1代碼示例:

EXPLAIN ANALYZE SELECT * FROM T WHERE a=101 OR b='A';
-> Filter: ((t.a = 101) or (t.b = 'A'))  (cost=717.14 rows=2056) (actual time=0.064..5.481 rows=2056 loops=1)
-> Index range scan on T using union(idx_a,idx_b)  (cost=717.14 rows=2056) (actual time=0.062..5.120 rows=2056 loops=1)

未使用索引合并的SQL2代碼示例:

EXPLAIN ANALYZE SELECT /*+ NO_INDEX_MERGE(T idx_a,idx_b) */ * FROM T WHERE a=101 OR b='A';
-> Filter: ((t.a = 101) or (t.b = 'A'))  (cost=10098.75 rows=10043) (actual time=0.038..31.129 rows=2056 loops=1)
-> Table scan on T  (cost=10098.75 rows=100425) (actual time=0.031..22.967 rows=100001 loops=1)

未使用索引合并時(shí),SQL2語(yǔ)句需要花費(fèi)約23ms來(lái)掃描全表100001行數(shù)據(jù),隨后再進(jìn)行條件判斷。而使用索引合并時(shí),通過(guò)合并兩個(gè)索引篩選出的主鍵id集合,篩選出2056個(gè)符合條件的主鍵id, 隨后回表獲取最終的數(shù)據(jù)。這個(gè)環(huán)節(jié)中,索引合并大大減少了需要訪(fǎng)問(wèn)的記錄數(shù)量。

此外,從SQL1和SQL3的查詢(xún)結(jié)果也可以看出,數(shù)據(jù)分布也會(huì)影響索引合并的效果。相同的SQL模板類(lèi)型,根據(jù)匹配數(shù)值的不同,查詢(xún)時(shí)間存在差異。如需要合并的主鍵id集合越小,需要回表的主鍵id越少,查詢(xún)時(shí)間越短。

EXPLAIN ANALYZE SELECT * FROM T WHERE a=101 OR b='A';
-> Filter: ((t.a = 101) or (t.b = 'A'))  (cost=717.14 rows=2056) (actual time=0.064..5.481 rows=2056 loops=1)
   -> Index range scan on T using union(idx_a,idx_b)  (cost=717.14 rows=2056) (actual time=0.062..5.120 rows=2056 loops=1)

EXPLAIN ANALYZE SELECT * FROM T WHERE a=10 OR b='A';
-> Filter: ((t.a = 10) or (t.b = 'A'))  (cost=983.00 rows=3057) (actual time=0.070..7.872 rows=3035 loops=1)
   -> Index range scan on T using union(idx_a,idx_b)  (cost=983.00 rows=3057) (actual time=0.068..7.496 rows=3035 loops=1)

總結(jié)

本文介紹了索引合并(Index Merge)包含的三種類(lèi)型,即交集(intersection)、并集(union)和排序并集(sort-union),以及索引合并的實(shí)現(xiàn)原理、場(chǎng)景約束與通過(guò)案例驗(yàn)證的優(yōu)缺點(diǎn)。在實(shí)際使用中,當(dāng)查詢(xún)條件列較多且無(wú)法使用聯(lián)合索引時(shí),就可以考慮使用索引合并,利用多個(gè)索引加速查詢(xún)。但要注意,索引合并并非在任何場(chǎng)景下均具有較好的效果,需要結(jié)合具體的數(shù)據(jù)分布進(jìn)行算法的選擇。

到此這篇關(guān)于MySQL使用索引合并(Index Merge)提高查詢(xún)效率的文章就介紹到這了,更多相關(guān)MySQL索引合并優(yōu)化及底層原理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MySQL如何實(shí)現(xiàn)兩張表取差集

    MySQL如何實(shí)現(xiàn)兩張表取差集

    這篇文章主要介紹了MySQL如何實(shí)現(xiàn)兩張表取差集問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • MySQL學(xué)習(xí)筆記2:數(shù)據(jù)庫(kù)的基本操作(創(chuàng)建刪除查看)

    MySQL學(xué)習(xí)筆記2:數(shù)據(jù)庫(kù)的基本操作(創(chuàng)建刪除查看)

    我們所安裝的MySQL說(shuō)白了是一個(gè)數(shù)據(jù)庫(kù)的管理工具,真正有價(jià)值的東西在于數(shù)據(jù)關(guān)系型數(shù)據(jù)庫(kù)的數(shù)據(jù)是以表的形式存在的,N個(gè)表匯總在一起就成了一個(gè)數(shù)據(jù)庫(kù)現(xiàn)在來(lái)看看數(shù)據(jù)庫(kù)的基本操作
    2013-01-01
  • Kubernetes中實(shí)現(xiàn) MySQL 讀寫(xiě)分離的詳細(xì)步驟

    Kubernetes中實(shí)現(xiàn) MySQL 讀寫(xiě)分離的詳細(xì)步驟

    Kubernetes中實(shí)現(xiàn)MySQL的讀寫(xiě)分離通過(guò)主從復(fù)制架構(gòu),利用Kubernetes部署MySQL主節(jié)點(diǎn)和從節(jié)點(diǎn),并通過(guò)Service實(shí)現(xiàn)讀寫(xiě)分離,提高數(shù)據(jù)庫(kù)性能和可維護(hù)性
    2024-11-11
  • MySQL如何修改binlog保存的天數(shù)

    MySQL如何修改binlog保存的天數(shù)

    本文介紹了如何修改MySQL的binlog保存天數(shù)為7天,設(shè)置了不會(huì)立即清除,需觸發(fā)特定條件,同時(shí)提到purge命令用于清除指定binlog,并舉例說(shuō)明
    2026-04-04
  • MySQL分區(qū)表的正確使用方法

    MySQL分區(qū)表的正確使用方法

    這篇文章主要給大家介紹了關(guān)于MySQL分區(qū)表的正確使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-01-01
  • 手把手帶你搞定MySQL全版本安裝與卸載

    手把手帶你搞定MySQL全版本安裝與卸載

    許多人在初次安裝MySQL時(shí),可能會(huì)遇到安裝錯(cuò)誤或選擇過(guò)高版本導(dǎo)致的問(wèn)題,這些問(wèn)題可能使數(shù)據(jù)庫(kù)無(wú)法正常使用,或者某些圖形界面無(wú)法操作,這篇文章主要介紹了MySQL全版本安裝與卸載的相關(guān)資料,需要的朋友可以參考下
    2026-04-04
  • 解決MySQL遇到錯(cuò)誤:1217 - Cannot delete or update a parent row: a foreign key constraint fails

    解決MySQL遇到錯(cuò)誤:1217 - Cannot delete or 

    這篇文章主要介紹了解決MySQL遇到錯(cuò)誤:1217 - Cannot delete or update a parent row: a foreign key constraint fails問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • sql?distinct多個(gè)字段的使用

    sql?distinct多個(gè)字段的使用

    這篇文章主要介紹了sql?distinct多個(gè)字段的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • MySql報(bào)錯(cuò)Table mysql.plugin doesn’t exist的解決方法

    MySql報(bào)錯(cuò)Table mysql.plugin doesn’t exist的解決方法

    一般產(chǎn)生原因是手工更改my.ini的數(shù)據(jù)庫(kù)文件存放地址導(dǎo)致的,大家可以參考下下面的方法
    2013-02-02
  • MySQL 索引分類(lèi)、最左匹配與失效場(chǎng)景問(wèn)題分析

    MySQL 索引分類(lèi)、最左匹配與失效場(chǎng)景問(wèn)題分析

    文章主要介紹了索引的概念、分類(lèi)及應(yīng)用,索引類(lèi)似書(shū)籍目錄,能提高查詢(xún)效率,分類(lèi)方面,文章詳細(xì)解析了B+樹(shù)索引的特點(diǎn)及其主鍵索引和二級(jí)索引的區(qū)別,并舉例說(shuō)明了索引的使用場(chǎng)景及失效情況,強(qiáng)調(diào)了最左匹配原則的重要性,感興趣的朋友跟隨小編一起看看吧
    2026-05-05

最新評(píng)論

博湖县| 泸水县| 苍南县| 大荔县| 渝中区| 洪洞县| 东乌珠穆沁旗| 镇赉县| 景洪市| 二连浩特市| 外汇| 金溪县| 钦州市| 揭阳市| 武城县| 龙南县| 虹口区| 东丰县| 寻甸| 教育| 乌苏市| 尼木县| 临沂市| 大港区| 潼关县| 黄梅县| 赤城县| 蒙自县| 长沙县| 桦甸市| 安龙县| 友谊县| 惠水县| 南平市| 贡山| 曲阜市| 吴忠市| 姜堰市| 红河县| 上栗县| 垫江县|