web-dev-qa-db-ja.com

インデックスを使用したSQLクエリの高速化

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分の夜間に新しいエントリを取得します。これはインデックスにどのように影響しますか?

インデックスを使用する場合、どの列を使用するのが最適であり、クラスター化インデックスと非クラスター化インデックスのどちらを使用する必要がありますか?

11
akd

ベストすべきことは、テーブルにある他のフィールドと、そのテーブルに対して実行する他のクエリによって異なります。

詳細がなければ、「価格」列を含む(コード、会社、作成日)の非クラスター化インデックスは確実にパフォーマンスを向上させます。

CREATE NONCLUSTERED INDEX IX_code_company_createddate
ON Products(code, company, createddate)
INCLUDE (price);

これは、そのインデックスを使用している場合、SQLはクエリの実行時に実際のテーブルにまったくアクセスしないためです。これは、インデックス内の特定の「コード、会社、作成日」を持つすべての行を検索でき、次のことができるためです。キーを定義するフィールドを使用すると、インデックスが高速アクセスを正確に可能にし、各行の「価格」値も持つため、それを本当に高速に実行します。

挿入に関しては、追加された行ごとに、SQL Serverもそれらをインデックスに追加する必要があるため、挿入のパフォーマンスに影響します。 SELECTパフォーマンスの向上が挿入への影響を上回ると期待する必要があると思いますが、それをテストする必要があります。

また、インデックスは、元のテーブルで使用されているスペース以外に、各行のすべてのフィールドを格納するため、より多くのスペースを使用します。

他の人がコメントで述べたように、PKをテーブルに追加することは(たとえそれが実際にはProductId列を追加することを意味しないとしてもneed)、同様に良い考えかもしれません。

12
eugenioy