1

これは、インデックス最適化理論に関する長く複雑な質問です。これは宿題ではありませんが、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、およびAmount_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つのセット間の内部JOINです。「最適化された」インデックスを使用すると、そのフィールドはインデックスリーフに含まれるため、プランナーは直接結果を返します。

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

4

2 に答える 2

1

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

于 2011-09-06T09:56:42.737 に答える
0

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

2つのインデックスは非常に似ています。「最適化された」ページにはリーフページに追加の列が含まれているため、そのインデックスを完全にスキャンすると、元のページと比較してより多くのページを読み取る必要がある可能性があります。ただし、少数の行が返されることになっている場合は、ルックアップを必要としないことの利点が、この小さな欠点をすぐに上回ると予想されます。

于 2011-09-06T09:57:31.930 に答える