SQL Server 2008インデックスの最適化 - クラスター化されたルックアップvsクラスター化

StackOverflow https://stackoverflow.com/questions/7317032

質問

これは、インデックス最適化理論に関する長く関与する質問です。これは宿題ではありませんが、Microsoftの70-432のサンプル試験でこの質問に最初にさらされました。元の質問は、一般的なクエリの最適化に関するものでしたが、説明できないこの独特の動作がわかりました。

まず、テーブル:

CREATE TABLE Invoice_details (
Invoice_id int NOT NULL,
Customer_id int NOT NULL,
Invoice_date datetime DEFAULT GETDATE() NULL,
Amount_total int NULL,
Serial_num int IDENTITY (1,1) NOT NULL)

ここで、クラスター化されたインデックスと、テスト用の2つのインデックス:

CREATE UNIQUE CLUSTERED INDEX [ix_serial] ON [dbo].[Invoice_details] ([Serial_num] ASC)
/* Below is the "original" index */
CREATE NONCLUSTERED INDEX [ix_invoice_customer] ON [dbo].[Invoice_details] 
    ([Invoice_id] ASC,[Customer_id] ASC)
/* Below is the "optimized" index (adds one included field) */
CREATE NONCLUSTERED INDEX [ix_invoice_customer_inc] ON [dbo].[Invoice_details] 
    ([Invoice_id] ASC,[Customer_id] ASC) INCLUDE ([Invoice_date])

また、いくつかのランダムテストデータをテーブルに追加しました-100000行。 Invoice_id、Customer_id、およびanieb_totalはそれぞれ独自のランダム値(範囲1000-9999)を受け取り、Invoice_dateはgetDate()にランダム数(範囲1000-9999)を受信しました。使用した実際のルーチンを提供できますが、詳細が関連するとは考えていませんでした。

そして最後に、クエリ:

SELECT Invoice_id,Customer_id,Invoice_date FROM Invoice_details WHERE Customer_id=1234;

明らかに、クエリの最初のステップは、クラスター化されていないインデックススキャンです。どのインデックスが使用されているかに関係なく、その最初のステップは同じ数のインデックス行を返します。 「元の」インデックスを使用すると、次のステップは、クラスター化されたインデックスを介した検索でInvoice_Dateを取得し、2つのセット間の内部結合が続きます。 「最適化された」インデックスを使用すると、そのフィールドはインデックスリーフに含まれるため、プランナーは結果を返すためにまっすぐ進みます。

どのインデックスがより速い実行をもたらしますか、そしてなぜですか?

役に立ちましたか?

解決

それは...に依存します 転換点.

他のヒント

断片化などの問題がないと仮定すると、クエリの選択性に帰着します。

2つのインデックスは非常に似ています。 「最適化された」ものには、リーフページに追加の列が含まれているため、そのインデックスの完全なスキャンは、元のページと比較してより多くのページを読む必要があることを意味する場合があります。ただし、ほんの一握りの行が返される場合は、このわずかな欠点を非常に迅速に上回るために検索を必要としないという利点が期待されます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top