web-dev-qa-db-ja.com

MySQLは単一のクエリに複数のインデックスを使用できますか?

複数の列を持つテーブル、たとえば、id, a, b, c, d, e。通常idで選択しますが、列のサブセットに対してさまざまな条件を使用するクライアントアプリには複数のクエリがあります。

MySQLが複数の列で複数のWHERE条件を持つ単一のテーブルでクエリを実行する場合、異なる列で作成されたインデックスを実際に使用できますか?または、高速化する唯一の方法は、可能なすべてのクエリに対して複数列インデックスを作成することですか?

44
kolypto

はい、MySQLは単一のクエリに複数のインデックスを使用できます。オプティマイザーは、どのインデックスがクエリに役立つかを決定します。 EXPLAINを使用して、MySQLがステートメントを実行する方法に関する情報を取得できます。次のようなヒントを使用して、インデックスを追加または無視できます。

SELECT * FROM t1 USE INDEX (i1) IGNORE INDEX FOR ORDER BY (i2) ORDER BY a;

MySQLがインデックスを使用する方法 を読むことをお勧めします。

ほんの少しの抜粋:

複数のインデックスから選択できる場合、MySQLは通常、最小の行数を見つけるインデックスを使用します。

Col1とcol2に複数列のインデックスが存在する場合、適切な行を直接フェッチできます。 col1とcol2に個別の単一列インデックスが存在する場合、オプティマイザーはインデックスマージ最適化(セクション8.3.1.4「インデックスマージ最適化」を参照)を使用するか、どのインデックスが少ないかを決定して最も制限の多いインデックスを見つけようとします。行を取得し、そのインデックスを使用して行をフェッチします。

57
Kermit

古典的に、MySQLは特定のクエリのテーブル参照ごとに1つのインデックスを使用できます。ただし、MySQLの最近のバージョンでは、index mergeと呼ばれる操作が行われ、MySQLがテーブルごとに複数のインデックスを使用できるようになります。

http://openquery.com/blog/mysql-50-index-merge-using-multiple-indexes

19
Chris Henry

Mysqlはインデックスマージを使用して、2つのインデックスの結果をマージできます。しかし、これは実際にはmysqlの好ましい方法ではありません。クエリの実行を最適化する場合、2つのインデックスを使用します。ただし、これはクエリ開発者が複合インデックスを作成するためのヒントでもあります。

インデックスのマージは、複合インデックスと決して同等ではありません。こちらはシュロンツ男爵の本からの抜粋です-

インデックスマージ戦略は非常にうまく機能する場合もありますが、実際にはインデックスが不十分なテーブルを示すことが一般的です。

•サーバーがインデックスと交差する場合(通常AND条件の場合)、通常は、結合する必要のある複数のインデックスではなく、関連するすべての列を持つ単一のインデックスが必要であることを意味します。
•サーバー結合インデックス(通常OR条件)の場合、アルゴリズムのバッファリング、並べ替え、およびマージ操作で多くのCPUおよびメモリリソースが使用されることがあります。これは、すべてのインデックスが非常に選択的ではない場合に特に当てはまるため、スキャンはマージ操作に多くの行を返します。

1
saurabh