web-dev-qa-db-ja.com

1つの列にインデックスを付ける場合と複数の列にインデックスを付ける場合の読み取りパフォーマンス

(MySQL、InnoDB)

列A、B、Cを持つテーブルがあります。そのテーブルには多数の行があります。たとえば、100万行としましょう。非常に頻繁に実行され、A列でテーブルを検索するクエリがあるので、A列にインデックスを追加しました。

最初のクエリほど頻繁には実行されないが、速度の向上に適格であるほど頻繁に実行される別のクエリがあります。このクエリは、3つの行すべてを検索します。

私の質問は、2番目のクエリで列Aのインデックスから速度が向上するか、または読み取り速度を向上させるために3つの列すべてにインデックスを追加する必要があるかです。言い換えると、3つのWHERE条件があるクエリでは、MySQLは最初にインデックス付きカラムで検索しますか?そうした場合、これらの100万行のうち、最初の列は100程度になる可能性があり、他の2つの列によるそれらのクエリは多少簡単で、インデックスを必要としません。

3
Vedran

インデックスはメインテーブルへのガイドです。したがって、最初のクエリは列Aのインデックスを使用して、テーブルのどの行に必要なデータがあるかを識別し、次にキー検索を実行して残りのデータを取得し、必要に応じてさらにフィルタリングします。

したがって、2番目のクエリもインデックスAを使用し、キールックアップを実行してから、必要に応じてさらにフィルタリングを実行します。

ただし、A、B、およびCにインデックスを1つだけ持つことができ、最初のクエリでもそのインデックスが使用されます(ただし、Aが最初の列にインデックスが付けられている場合)。

だから、ケーキを持って食べてもいい。両方のインデックスを作成するのではなく、A、B、Cにインデックスを作成します。ただし、テーブルが狭く、4列または5列しかない場合は、Aにのみインデックスを作成します。

3
Jonathan Fite

次のインデックスが必要だとします。

_INDEX(a)
_

_WHERE a = 123_または_WHERE a > 876_の場合;そして

_INDEX(a, b, c)
_

_WHERE a=3 AND b=3 AND c > 666_の場合。

2番目のインデックスは、最初のインデックスに対して指定した両方の例を処理します。したがって、事実上すべての状況で、DROPINDEX(a)を実行する必要があります。

適切なインデックスの作成の詳細: http://mysql.rjweb.org/doc.php/index_cookbook_mysql

(状況の詳細を提供していただければ、ここで対処します。)

2
Rick James

より多くのインデックスはより多くのメモリ(RAM)を使用します。また、各インデックスは挿入、更新、または削除後に更新する必要があるため、挿入と削除の時間に影響を与える可能性があります。

列Aのみにインデックスを追加することを検討します。

0
ttwis

あなたのような100万行のテーブルの場合(将来的にさらに大きくなる可能性があります)、3つの列に複合インデックスを作成します。最初の列は、個別に検索する列にする必要があります。そう:

ALTER TABLE yourtable ADD INDEX idx_all (`A`, `B`, `C`);

または:

ALTER TABLE yourtable ADD INDEX idx_all2 (`A`, `C`, `B`); -- if column C is more selective than B.

これは両方のクエリパターンに有効です。最初のクエリは最初の列のみを使用し、2番目のクエリは3つの列を使用します。

0
anisakras