たとえば、複数の列を持つテーブルを想像してみてくださいid, a, b, c, d, e
。私は通常、によって選択しますがid
、クライアントアプリには、列のサブセットに対してさまざまな条件を使用する複数のクエリがあります。
MySQLが複数の列に複数のWHERE条件を持つ単一のテーブルでクエリを実行する場合、異なる列に作成されたインデックスを実際に利用できますか?または、高速化する唯一の方法は、考えられるすべてのクエリに対して複数列のインデックスを作成することですか?
たとえば、複数の列を持つテーブルを想像してみてくださいid, a, b, c, d, e
。私は通常、によって選択しますがid
、クライアントアプリには、列のサブセットに対してさまざまな条件を使用する複数のクエリがあります。
MySQLが複数の列に複数のWHERE条件を持つ単一のテーブルでクエリを実行する場合、異なる列に作成されたインデックスを実際に利用できますか?または、高速化する唯一の方法は、考えられるすべてのクエリに対して複数列のインデックスを作成することですか?
はい、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.2.1.4「インデックスマージ最適化」を参照)、どちらのインデックスが少ないかを判断して最も制限の厳しいインデックスを見つけようとします。行とそのインデックスを使用して行をフェッチします。
従来、MySQLは、特定のクエリでテーブル参照ごとに1つのインデックスを使用できます。ただし、MySQLの最近のバージョンでは、anと呼ばれる操作が実行され、index merge
MySQLがテーブルごとに複数のインデックスを使用できるようになります。
http://openquery.com/blog/mysql-50-index-merge-using-multiple-indexes
Mysqlは、インデックスマージを使用して、2つのインデックスの結果をマージできます。しかし、これはmysqlの実際に好ましい方法ではありません。クエリの実行を最適化する場合は、2つのインデックスを使用します。ただし、これはクエリ開発者が複合インデックスを作成するためのヒントでもあります。
インデックスのマージは、複合インデックスと同等ではありません。これがバロンシュワルツの本からの抜粋です-
インデックスマージ戦略は非常にうまく機能する場合がありますが、実際にはインデックスが不十分なテーブルを示していることがより一般的です。
•サーバーがインデックスと交差する場合(通常はAND条件の場合)、通常、結合する必要のある複数のインデックスではなく、関連するすべての列を含む単一のインデックスが必要であることを意味します。
•サーバーユニオンがインデックスを作成する場合(通常はOR条件の場合)、アルゴリズムのバッファリング、並べ替え、およびマージ操作で大量のCPUおよびメモリリソースが使用されることがあります。これは、すべてのインデックスが非常に選択的ではない場合に特に当てはまります。そのため、スキャンによって多くの行がマージ操作に返されます。
SELECT
(think UNION
、subquery、派生テーブルなど)は、個別に最適化されます。つまり、それぞれが異なるインデックスを使用する可能性があります。SELECT
。これはめったに使用されません。EXPLAIN
を使用していると言う場合Index merge (intersect)
、交差するインデックスで使用される列を含む複合インデックスを使用することで、ほとんどの場合、改善できます。Index merge (union)
時々(まれに)に使用されますOR
。これは、クエリを2つに書き直すことで改善できる可能性があります。UNION
SELECTs