何百万ものレコードを含む可能性のあるSQLServer2008データベースを作成していますが、以下をインデックスとして定義する必要があるかどうか疑問に思いました。
0と1のみを含む可能性のあるTINYINT列?
0、5、および6のみを含む可能性のあるTINYINT列?
PS。これらの列は両方とも、WHERE句で選択に使用されます。
何百万ものレコードを含む可能性のあるSQLServer2008データベースを作成していますが、以下をインデックスとして定義する必要があるかどうか疑問に思いました。
0と1のみを含む可能性のあるTINYINT列?
0、5、および6のみを含む可能性のあるTINYINT列?
PS。これらの列は両方とも、WHERE句で選択に使用されます。
いいえ、これらの列のインデックスだけは基本的に使用されません。
ただし、このような選択性の低いキーは、インデックスの左端の列として配置される複合キーの優れた候補になります。たとえば、TINYINT (0,1)
(なぜbit
btwを使用しないのですか?)がdeleted
列であると言います。を述語とするクエリが頻繁にありWHERE deleted=0 AND ...
ます。これをクラスター化インデックスの左端の列として追加することは、多くの場合、適切なアプローチです。または、述語がたとえばであるWHERE name = '...' AND deleted=0
場合は、非クラスター化を作成する必要がありますindex on (deleted, name)
。
別のオプションは、フィルターされたインデックスを使用することです:しかし、これはあなたが興味を持ってcreate index .. on (name) where (deleted=0)
いる場合をカバーしていません。deleted=1
たとえば、列のように明確な値がほとんどない列についても同じことが言えtype
ます。繰り返しになりますが、これを複合インデックスの左端のキーにすることは、通常、非常に理にかなっています。
ただし、インデックスの左端のキーとして選択性の低いキーを追加し、述語でこの列を指定しないWHERE name='...'
場合(たとえば、の基準を追加しない場合deleted
)、インデックスは使用できず、インデックスon (name)
(またはon (name, ...)
)を使用できます。name
左端のキーはどこですか。
一番右の鍵にしてみませんか?例えば。index on (name, deleted)
?通常はメリットがないため、一意の制約を適用する場合に限ります。から選択するのは0または1のみで、index on (name)
またはindex on (name, deleted)
基本的に同じパフォーマンスを提供します(使用できる場合)。選択性の低いキーを左側に配置すると、一部の範囲スキャンシナリオが有効になります(例WHERE type=5
)。
インデックスの選択性が低くなるため、これは良い考えではありません。これにより、「スピードアップ」ではなく、欠点になる可能性があります。
インデックスの選択性は、同じ値を持つ行が少ないほど優れています
他のいくつかのケースでは、全表スキャンでさえより効果的である可能性があります。
たとえば、100万行あります。その場合、最初のインデックスの選択性は次のとおりです。
(選択性=個別の値/行)
2 / 1.000.000 = 0,000002
その他の場合:
3 / 1.000.000 = 0,000003
これらの値は非常に低いです!
または別の方法で:
推定選択性比率=(TotalRows /個別の値)/ TotalRows * 100 = 1/Distinc値*100。
最初のケースでは50%、2番目のケースでは33%です。
SQL Serverのオプティマイザーは、この比率が15%を超えるインデックスを使用しません。
(私の計算は簡単な見積もりですが、 MSDNで統計情報を見つけることができます)