web-dev-qa-db-ja.com

含まれている列がupdateステートメントを使用して更新されると、非クラスター化インデックスはどうなりますか?

列が含まれる非クラスター化インデックスに関する質問(DB-MS SQL Server)。私はブログを読みました 最適化された非クラスター化インデックスのメンテナンス 更新ステートメントが実行され、クラスター化インデックスと非クラスター化インデックスがテーブルに定義されている場合のクエリプランに関する情報を提供します。
列が含まれている非クラスター化インデックスについて質問があります。私はブロガーによって提供された同じ例を参照しています

CREATE TABLE T (PK INT, A INT, B INT, C INT, D INT, E INT)
CREATE UNIQUE CLUSTERED INDEX TPK ON T(PK)

CREATE INDEX TB ON T(B)
CREATE INDEX TCD ON T(C,D)
CREATE INDEX TE ON T(E)

-これは、列が含まれる新しい非クラスター化インデックスです

CREATE INDEX TF ON T(E) INCLUDE(A)


INSERT T VALUES(0, 10, 20, 30, 40, 50)

UPDATE T SET A = 19

インデックスTFが定義されていない場合、クラスター化インデックスの更新のみが実行され、非クラスター化インデックスの挿入および削除操作は実行されません。しかし、TFが定義されるとどうなりますか?

7
Delta

あなたが参照するブログの投稿は、あなたがこれに自分でどう答えたかを示しています。

実行すると

SET SHOWPLAN_TEXT ON;
GO
UPDATE T SET A = 19;

計画は次のようになります

  |--Clustered Index Update(OBJECT:([AdventureWorks2008].[dbo].[T].[TPK]), OBJECT:([AdventureWorks2008].[dbo].[T].[TF]), SET:([AdventureWorks2008].[dbo].[T].[A] = [@1]))
       |--Compute Scalar(DEFINE:([Expr1009]=[Expr1009]))
            |--Compute Scalar(DEFINE:([Expr1009]=CASE WHEN CASE WHEN [AdventureWorks2008].[dbo].[T].[A] = [@1] THEN (1) ELSE (0) END THEN (0) ELSE (1) END))
                 |--Top(ROWCOUNT est 0)
                      |--Index Scan(OBJECT:([AdventureWorks2008].[dbo].[T].[TF]), ORDERED FORWARD)

更新されたオブジェクトの1つとしてインデックスTFがリストされている、行ごと/狭いプランを示しています。

4
Martin Smith

リーフページと非リーフページに格納されているインデックスの値を更新するときと同じように、これらのページはすべて新しい値で更新されます。インクルードによってのみリーフレベルで格納された列は、値を更新すると更新されます。これにより、ページ分割が発生する可能性もあります。

4
Grant Fritchey

TFが定義されている場合は、更新する必要があります。これは、Aの値がTFリーフレベルに含まれているためです。列Aの更新は、この値をインデックスTFに反映する必要があります。

これが、インクルードインデックスTFがある理由です。これにより、列EまたはAのみが必要な場合に、Aを検索する必要がなくなります。

2
StanleyJohns