定期的にクエリを実行するテーブル(大きくなる可能性があり、数百万行になる可能性があります)がありSELECT * from table WHERE somefield = 20
、このクエリを高速に実行したいと思います。いつでも、このクエリは、この特定の値20に対して、数百万の可能性のうち最大10行を返すことを期待しています(他の値の保証はありません)。これを索引付けする適切な方法は何でしょうか?あるフィールドにインデックスを配置し、統計がほぼ最新であることを確認するだけで十分ですか?それとも、これを最適化するために試みることができる他のトリックはありますか?
3 に答える
あるフィールドにインデックスを配置し、統計がほぼ最新であることを確認するだけで十分ですか?
はい、非常に簡単です。somefieldが正しいタイプ(つまりint)であることを確認してください。somefieldにテキストを含める必要がある場合は、さらに多くのことができますが、それ以外の場合は通常のインデックスで問題ありません。
使用しないことで返されるすべてのフィールドが必要ない場合は、わずかな増加を得ることができますSELECT *
(おそらく、それが何であるかをすでに知っているので、somefieldは必要ありません)。
このクエリを単独で使用する場合の理想的なインデックスは、キー列somefield
とテーブル内の他のすべての列の列を含むインデックスです(インデックスをクラスター化するか、INCLUDE
オプションを使用してNCIを作成します)。
これにより、値を直接検索できるようになり、ブックマークを検索する必要がなくなります。
ただし、これらすべての列が含まれるNCIのメンテナンスオーバーヘッドはデータ変更操作に影響を与えるため、他のクエリに役立つか、とにかく断片化を回避するために、異なるキー列で定義されたCIを使用することをお勧めします。
そのため、NCIをsomefield
単独で定義し、10個のブックマークルックアップを使用することをお勧めします。それはバランスをとる行為です。
編集。実際、クエリの最適化のみに関心がある場合は、その値に対してフィルター処理されたインデックスsomefield = 20
を作成できます。その場合、そのインデックス定義のすべての列になる可能性があります。include
はい、somefieldにインデックスを追加する必要があります。
他のクエリを実行していない場合は、それをクラスター化されたインデックスにすることをお勧めしますが、コンテキストがなければ、決定的に言うのは難しいです。