Products
というテーブルがあります。
このテーブルには、300万を超えるエントリが含まれています。毎日約5000の新しいエントリがあります。これは、夜間に2分間だけ発生します。
しかし、このテーブルは、このクエリで毎晩2万回以上クエリされます。
SELECT Price
FROM Products
WHERE Code = @code
AND Company = @company
AND CreatedDate = @createdDate
テーブル構造:
Code nvarchar(50)
Company nvarchar(10)
CreatedDate datetime
このクエリがProducts
テーブルから結果を返すのに約1秒かかることがわかります。
必要がないため、テーブルにはproductId
列はありません。したがって、テーブルには主キーはありません。
結果をより早く返すように、このクエリをどうにか改善したいと思います。
これまでインデックスを使用したことがありません。このテーブルでインデックスを使用する最良の方法は何ですか?
主キーを指定すると、クエリ結果が高速になると思いますか? 3つのパラメータを指定してテーブルをクエリする必要があることに注意してください。
WHERE Code = @code
AND Company = @company
AND CreatedDate = @createdDate.
これは必須です。
先ほど触れたように、テーブルは毎日2分の夜間に新しいエントリを取得します。これはインデックスにどのように影響しますか?
インデックスを使用する場合、どの列を使用するのが最適であり、クラスター化インデックスと非クラスター化インデックスのどちらを使用する必要がありますか?
ベストすべきことは、テーブルにある他のフィールドと、そのテーブルに対して実行する他のクエリによって異なります。
詳細がなければ、「価格」列を含む(コード、会社、作成日)の非クラスター化インデックスは確実にパフォーマンスを向上させます。
CREATE NONCLUSTERED INDEX IX_code_company_createddate
ON Products(code, company, createddate)
INCLUDE (price);
これは、そのインデックスを使用している場合、SQLはクエリの実行時に実際のテーブルにまったくアクセスしないためです。これは、インデックス内の特定の「コード、会社、作成日」を持つすべての行を検索でき、次のことができるためです。キーを定義するフィールドを使用すると、インデックスが高速アクセスを正確に可能にし、各行の「価格」値も持つため、それを本当に高速に実行します。
挿入に関しては、追加された行ごとに、SQL Serverもそれらをインデックスに追加する必要があるため、挿入のパフォーマンスに影響します。 SELECTパフォーマンスの向上が挿入への影響を上回ると期待する必要があると思いますが、それをテストする必要があります。
また、インデックスは、元のテーブルで使用されているスペース以外に、各行のすべてのフィールドを格納するため、より多くのスペースを使用します。
他の人がコメントで述べたように、PKをテーブルに追加することは(たとえそれが実際にはProductId列を追加することを意味しないとしてもneed)、同様に良い考えかもしれません。