4

いくつかのテーブルがあり、複合インデックスが役立つかどうか疑問に思っています。私は使用してMySQL 5+いますが、これはどのデータベースにも当てはまると思います(または当てはまりませんか?)。

とにかく、次の表を言ってください:

username           active
-----------------------------------
Moe.Howard              1
Larry.Fine              0
Shemp.Howard            1

だから私は通常次のように選択します:

select * from users where username = 'shemp.howard' and active = 1;

active=1、多くのテーブルで使用されています。通常、私のインデックスはusername列にありますが、アクティブフラグも(同じインデックスに)追加することを考えています。

私の論理は、クエリエンジンがインデックスをスキャンしているとき、次のようなインデックスに対してスキャンすることです:

moe.howard,1
shemp.howard,1
larry.fine,0

非アクティブなユーザーにヒットする前に見つけShempます (Larry)。

さて、私たちのactive列は通常TINYINTSUnsignedです。しかし、インデックスが逆になっているのではないかと心配しています!

larry.fine,0
moe.howard,1
shemp.howard,1

これをどのように処理し、インデックスが正しいことを確認するにはどうすればよいですか? アクティブな列をユーザー名と同じインデックスに追加すべきではありませんか? または、アクティブ用に別のインデックスを作成して降順にする必要がありますか?

ありがとう。

4

3 に答える 3

2

キーの 2 番目の部分としてフラグを使用して複合インデックスでこれら 2 つのフィールドを組み合わせるとactive、インデックスの順序は、2 つ以上の行の名前フィールドが同一である場合にのみ、その値に依存します (これは、この状況は、システム内のユーザー名を一意にする必要があるという前提に基づいています)。複合インデックスの最初のキーは、キーが異なる場合は常にキーの順序を定義します。つまり、ユーザー名が一意の場合、アクティブ フラグを複合インデックスの 2 番目のセグメントとして追加しても、インデックスの順序は変更されません。

また、クエリの例では、データベースはインデックスを「スキャン」して値を見つけないことに注意してください。代わりに、最初に一致したエントリ (この例では 1 つの一致で構成されています) を探します。複数のエントリが WHERE 句を通過すると、「スキャン」が発生します。

そうは言っても、名前が重複しているケースが多くない限り、私の最初の反応は、複合キーを作成しないことです。名前が「一般的に」一意である場合、複合キーで多くの節約を購入することはありません。一方、activeフラグ値が異なる重複した名前が一般的にかなりある場合は、それが役立つ可能性があります。その時点で、テストする必要があるかもしれません。

于 2013-03-12T13:59:12.840 に答える
2

実際には、クエリ オプティマイザが何を試みて何を行うかは、後から推測するしかありませんが、一般的に、インデックスの選択性が 20% を超える場合は、インデックス アクセスよりもフル テーブル スキャンを使用することをお勧めします。これは、アクティブなインデックスを作成したとしても、非アクティブなユーザーよりも多くのアクティブなユーザーがいると仮定すると、実際にはインデックスが使用されない可能性が非常に高いことを意味します。

MySQL はインデックスを順番にしか使用できないため、複合インデックスを作成してusername,activeも、同じユーザー名を持つ複数のユーザーが存在しないため、まったく意味がありません。

クエリの要件を分析する必要があり、それらに合わせてインデックス作成プランを設計できます。各クエリをプロファイリングし、すべてを過度に最適化しようとしないでください。これはマイナスの結果になる可能性があります。

于 2013-03-12T13:59:34.993 に答える
1

インデックスは、統計的に言えば、フィルターイン/フィルターアウトに役立つと予想される値が代表的なものである場合にのみ追加する必要があります。

どういう意味ですか?

たとえば、インデックスを作成している列のWHERE句のフィルターが、行の20%を取得するのに役立つ場合は、インデックスを追加する必要があります。このパーセント数は特殊なケースによって異なり、試してみる必要がありますが、それがアイデアです。

あなたの場合、名前だけで、100%除外されます。アクティブな列にインデックスを追加しても、最終的なレコードセットを減らすのに役立たないため、役に立たないでしょう(ただし、同じ名前がn回あるが、アクティブな名前が1つしかない場合を除く)。

名前を気にせずにアクティブユーザーのみをフィルタリングすることにした場合は、状況が異なります。

于 2013-03-12T14:01:46.643 に答える