web-dev-qa-db-ja.com

MySQLの2つの単一列インデックスと1つの2列インデックス

私は次のことに直面しており、ベストプラクティスが何であるか分かりません。

次の表を検討してください(大きくなります):

id PK | giver_id FK | recipient_id FK |日付

私はInnoDBを使用していますが、理解していることから、2つの外部キー列のインデックスが自動的に作成されます。ただし、次の特定の組み合わせに一致する必要がある場合は、多くのクエリも実行します。

SELECT...WHERE giver_id = x AND recipient_id = t

このような各組み合わせは、テーブル内で一意です。

これらの列に2列のインデックスを追加することで何か利点はありますか、それとも理論的には2つの個別のインデックスで十分/同じでしょうか?

97
Tom

2つの単一列インデックスがある場合、例ではそのうちの1つだけが使用されます。

2列のインデックスがある場合、クエリは高速になる可能性があります(測定する必要があります)。 2列のインデックスを単一の列インデックスとして使用することもできますが、これは最初にリストされている列に対してのみです。

インデックスを(A、B)に、別のインデックスを(B)にすると便利な場合があります。これにより、どちらかまたは両方の列を使用したクエリが高速になりますが、もちろんより多くのディスク容量も使用します。

インデックスを選択するときは、挿入、削除、更新への影響も考慮する必要があります。インデックスが多いほど、更新が遅くなります。

114
Mark Byers

次のようなカバリングインデックス:

ALTER TABLE your_table ADD INDEX (giver_id, recipient_id);

...クエリがgiver_id、またはgiver_idrecipient_idの組み合わせを参照する場合、インデックスを使用できることを意味します。インデックス条件は左端に基づいていることに注意してください-recipient_idのみを参照するクエリは、提供したステートメントでカバーインデックスを使用できません。

また、MySQLはSELECTごとに1つのインデックスしか使用できないため、クエリを最適化する最良の方法はカバーインデックスです。

26
OMG Ponies

外部キーインデックスの1つが既に非常に選択的である場合、データベースエンジンは指定されたクエリに対してその1つを使用する必要があります。ほとんどのデータベースエンジンは、そのような状況で最適なインデックスを選択できるように、ある種のヒューリスティックを使用します。どちらのインデックスもそれ自体で高度に選択的ではない場合、そのタイプのクエリを頻繁に使用すると言うので、おそらく両方のキーに構築されたインデックスを追加するのが理にかなっています。

考慮すべきもう1つのことは、このテーブルのPKフィールドを削除し、giver_idおよびrecipient_idフィールドで主キーインデックスを定義できるかどうかです。あなたはその組み合わせがユニークであると言ったので、おそらくうまくいくでしょう(あなただけが答えることができる他の多くの条件が与えられた場合)。ただし、通常、追加する複雑さは面倒な価値はないと思います。

4
Mark Wilkins

考慮すべきもう1つの点は、両方のアプローチのパフォーマンス特性が、データセットのサイズとカーディナリティに基づいていることです。 2列のインデックスは、特定のデータセットサイズのしきい値、またはその逆の場合にのみパフォーマンスが向上することに気付く場合があります。正確なシナリオのパフォーマンスメトリックに代わるものはありません。

1
Andrew