Cell_ID
、Cell
、CellValue
などの列があるCellRow
という名前のテーブルがあります。
Cellrow
の最大値は1〜5です。Cell_
IDフィールドにはクラスター化インデックスがあります。このテーブルには100000行が含まれています。
私のクエリでは、CellRow
フィールドからデータを取得するために、CellRow > 3
のようなWHERE句でCellValue
列を使用する必要があります。問題は、このように実行すると、クエリが非常に遅くなるのは常にテーブルスキャンであるということです。
また、CellRow
フィールドに非クラスター化インデックスを配置してチェックしましたが、CellRow
フィールドにはそれほど多くの値がなく、毎回1〜5個しかありません。 where句でCellID
を使用できません。
私は私のクエリで多くのテーブルを使用しています
Table_1
はクラスター化インデックス列を使用してtable_2
と結合しており、table 2
は非クラスター化インデックス列を使用してtable_3
と結合しており、table_3
はCell
テーブルと結合しています非クラスター化インデックスを使用する。
結局のところ、セルテーブルを含むすべてのテーブルから異なる値を取得していますが、WHERE句でCellRow
フィールドを使用すると、インデックススキャンを取得しています。
任意のソリューション:)
どうもありがとうございます!
任意のソリューション:)
いいえ、そうではありません。
あなたが言ったように-CellRow
はあまり選択的ではありません-5つの可能な値、100'000行=可能な各値のおよそ20'000行。
SQL Serverのクエリオプティマイザーはこれを認識し、おそらく20,000行のシークよりもインデックススキャンを実行する方が簡単で効率的であると考えています。
これを回避する唯一の方法は、より選択的なインデックス、つまり、2%、3%、または最大を選択する他の列を使用することです。各クエリの行の5%。
PS:実行計画を確認してください-インデックスから直接値を取得しますか、それともデータを取得するために「キー検索」ステップが必要ですか?
列のデータ型については言及していませんでした。CellValue
が大きすぎない場合は、インデックスに追加して(または少なくともインデックスに含めることで)、コストのかかるキールックアップを回避できます。
CREATE INDEX IX_CellRow_CellValues
ON dbo.Cell(CellRow) INCLUDE(CellValue)
ただし、インデックススキャンは引き続き可能です。
cellrowにインデックスを作成しますが、値が5つしかない場合、オプティマイザはそれを使用しないと決定する可能性がありますが、3を超える値がまれであることがわかっている場合、クエリにヒントを追加して、エンジンがそのインデックスを使用するようにすることができます。
編集:別のテーブルでセル行を分離し、セル行4と5のテーブルの結合であるビューを作成して、そのビューでクエリを実行することで、動作するかどうかわからない別のより複雑なソリューションがあります。 、インデックスは使用しませんが、関連するレコードをトラバースするだけです。これは、データディクショナリが行うことの一種ですが、メンテナンスが増えるため(たとえば、データが3から4に変更され、1回の更新ではなく、テーブル '3'から削除されてテーブルに挿入されるため)、注意が必要ですたとえば「4」)。最終的にそれはあなたのニーズに依存します。通常、この種のことは何百万ものレコードについて話しているときに行われますが、それが自分のために行われるかどうかを試すことができます。
私はWHERE CellRow in (4, 5)
がWHERE CellRow > 3
よりもうまく機能することを期待します。 ----