regrupting転載時にソースを示してください:MySQLインデックスの合併:1つのSQLが複数のインデックスを使用できます
The Index Merge method is used to retrieve rows with several range scans and to merge their results into one. The merge can produce unions, intersections, or unions-of-intersections of its underlying scans. This access method merges index scans from a single table; it does not merge scans across multiple tables.1. インデックス マージとは、複数のインデックスの範囲スキャンを 1 つのインデックスにマージすることです。
2. インデックスを結合する場合、インデックスは最初に結合、交差、または交差してから結合されて 1 つのインデックスになります。
3. マージする必要があるこれらのインデックスは 1 つのテーブルにのみ所属できます。複数のテーブルに対してインデックスのマージを実行することはできません。
union Index を使用して共用体を取得する
sort_union を使用して、取得したデータを最初に ROWID でソートし、次に共用体を取得する
intersect を使用してインデックスの共通部分を取得する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
mysql> show create table test\G *************************** 1. row *************************** Table: test Create Table: CREATE TABLE `test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `key1_part1` int(11) NOT NULL DEFAULT '0', `key1_part2` int(11) NOT NULL DEFAULT '0', `key2_part1` int(11) NOT NULL DEFAULT '0', `key2_part2` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), KEY `key1` (`key1_part1`,`key1_part2`), KEY `key2` (`key2_part1`,`key2_part2`) ) ENGINE=MyISAM AUTO_INCREMENT=18 DEFAULT CHARSET=utf8 1 row in set (0.00 sec) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
mysql> select * from test; +----+------------+------------+------------+------------+ | id | key1_part1 | key1_part2 | key2_part1 | key2_part2 | +----+------------+------------+------------+------------+ | 1 | 1 | 1 | 1 | 1 | | 2 | 1 | 1 | 2 | 1 | | 3 | 1 | 1 | 2 | 2 | | 4 | 1 | 1 | 3 | 2 | | 5 | 1 | 1 | 3 | 3 | | 6 | 1 | 1 | 4 | 3 | | 7 | 1 | 1 | 4 | 4 | | 8 | 1 | 1 | 5 | 4 | | 9 | 1 | 1 | 5 | 5 | | 10 | 2 | 1 | 1 | 1 | | 11 | 2 | 2 | 1 | 1 | | 12 | 3 | 2 | 1 | 1 | | 13 | 3 | 3 | 1 | 1 | | 14 | 4 | 3 | 1 | 1 | | 15 | 4 | 4 | 1 | 1 | | 16 | 5 | 4 | 1 | 1 | | 17 | 5 | 5 | 1 | 1 | | 18 | 5 | 5 | 3 | 3 | | 19 | 5 | 5 | 3 | 1 | | 20 | 5 | 5 | 3 | 2 | | 21 | 5 | 5 | 3 | 4 | | 22 | 6 | 6 | 3 | 3 | | 23 | 6 | 6 | 3 | 4 | | 24 | 6 | 6 | 3 | 5 | | 25 | 6 | 6 | 3 | 6 | | 26 | 6 | 6 | 3 | 7 | | 27 | 1 | 1 | 3 | 6 | | 28 | 1 | 2 | 3 | 6 | | 29 | 1 | 3 | 3 | 6 | +----+------------+------------+------------+------------+ 29 rows in set (0.00 sec) |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
mysql> explain select * from test where (key1_part1=4 and key1_part2=4) or (key2_part1=4 and key2_part2=4)\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: test type: index_merge possible_keys: key1,key2 key: key1,key2 key_len: 8,4 ref: NULL rows: 3 Extra: Using sort_union(key1,key2); Using where 1 row in set (0.00 sec) |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
mysql> explain select * from test where (key1_part1=1 and key1_part2=1) or key2_part1=4\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: test type: ALL possible_keys: key1,key2 key: NULL key_len: NULL ref: NULL rows: 29 Extra: Using where 1 row in set (0.00 sec) |
上記 2 つのケースから、同じモードの SQL 文でもインデックスが使用できる場合と使用できない場合があることがわかります。インデックスを使用できるかどうかは、統計データを分析した後、MySQL クエリ オプティマイザーがインデックスを使用した方が高速であると判断するかどうかによって決まります。
したがって、SQL ステートメントでインデックスを使用できるかどうかを単純に議論するのは少し一方的であり、データについても考慮する必要があります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
mysql> show create table test\G *************************** 1. row *************************** Table: test Create Table: CREATE TABLE `test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `key1_part1` int(11) NOT NULL DEFAULT '0', `key1_part2` int(11) NOT NULL DEFAULT '0', `key2_part1` int(11) NOT NULL DEFAULT '0', `key2_part2` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), KEY `key1` (`key1_part1`,`key1_part2`,`id`), KEY `key2` (`key2_part1`,`key2_part2`,`id`) ) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=utf8 1 row in set (0.00 sec) |
数据结构和之前有所调整。主要调整有如下两方面:
1、引擎从myisam改为了innodb。
2、组合索引中增加了id,并把id放在最后。
数据和上面的数据一样。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
mysql> explain select * from test where (key1_part1=4 and key1_part2=4) or (key2_part1=4 and key2_part2=4)\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: test type: index_merge possible_keys: key1,key2 key: key1,key2 key_len: 8,8 ref: NULL rows: 2 Extra: Using union(key1,key2); Using where 1 row in set (0.00 sec) |
同じデータ、同じ SQL ステートメントですが、データ テーブルの構造が sort_union から Union に調整されています。理由はいくつかあります。
1. インデックスを通じて取得されたデータが ROWID によってソートされている限り、Union を使用できます。
2. 結合されたインデックスの最後に id フィールドを追加します。目的は、インデックスの最初の 2 つのフィールドによって取得されたデータを ID で並べ替えることです。
3. エンジンを myisam から innodb に変更します。目的は、ID と ROWID の順序を一致させることです。
mysql インデックスのマージ: 1 つの SQL で複数のインデックスを使用できます
http://www.php.cn/
上記は mysql インデックスのマージの内容です: 1 つの SQL で複数のインデックスを使用できます。 PHP 中国語 Web サイト (www.php.cn) のコンテンツに注目してください。