インデックスマージアクセス方法では、複数の range
スキャンを含む行が取得され、その結果が 1 つにマージされます。 このアクセス方法では、単一のテーブルからのみインデックススキャンがマージされ、複数のテーブルにわたるスキャンはマージされません。 このマージによって、その基盤となるスキャンの和集合、共通集合、または共通集合の和集合を生成できます。
インデックスマージを使用できるクエリーの例:
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
出力では、インデックスマージメソッドは type
カラムに index_merge
と表示されます。 この場合、key
カラムには使用されたインデックスのリストが含まれ、key_len
にはそれらのインデックスの最長のキーパートのリストが含まれます。
インデックスマージアクセス方法には、EXPLAIN
出力の Extra
フィールドに表示されるいくつかのアルゴリズムがあります:
Using intersect(...)
Using union(...)
Using sort_union(...)
次の各セクションでは、これらのアルゴリズムについて詳しく説明します。 オプティマイザは、使用可能な様々なオプションのコスト見積りに基づいて、様々なインデックスマージアルゴリズムとその他のアクセス方法のいずれかを選択します。
このアクセスアルゴリズムは、WHERE
句が AND
と組み合された異なるキーの複数の範囲条件に変換され、各条件が次のいずれかである場合に適用されます:
-
この形式の
N
部分式。インデックスには正確にN
部分が含まれます (つまり、すべてのインデックス部分が対象となります):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
テーブルの主キーに対する条件である場合、行の取得には使用されませんが、他の条件を使用して取得された行を除外するために使用されます。
このアルゴリズムの基準は、インデックスマージ交差アルゴリズムの基準と似ています。 このアルゴリズムは、テーブルの 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;
このアクセスアルゴリズムは、WHERE
句が OR
で結合された複数の範囲条件に変換されるが、インデックスマージ結合アルゴリズムが適用できない場合に適用できます。
例:
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;
ソート和集合アルゴリズムと和集合アルゴリズムの違いは、ソート和集合アルゴリズムでは、行を返す前にまずすべての行の行 ID をフェッチし、それらをソートする必要があることです。
インデックスマージの使用は、optimizer_switch
システム変数の index_merge
, index_merge_intersection
, index_merge_union
および index_merge_sort_union
フラグの値の影響を受けます。 セクション8.9.2「切り替え可能な最適化」を参照してください。 デフォルトでは、これらのフラグはすべて on
です。 特定のアルゴリズムのみを有効にするには、index_merge
を off
に設定し、許可される他のアルゴリズムのみを有効にします。
MySQL では、optimizer_switch
システム変数を使用してインデックスマージアルゴリズムのセッション全体のオプティマイザ使用を制御することに加えて、オプティマイザヒントをサポートしてステートメントごとにオプティマイザに影響を与えます。 セクション8.9.3「オプティマイザヒント」を参照してください。