web-dev-qa-db-ja.com

非永続計算列SQLサーバーでの非クラスター化インデックスの作成

SQL Serverが非永続計算列を実際に格納する方法に関するドキュメントを見つけるのに苦労しています。

次の例を見てください。

--SCHEMA
CREATE TABLE dbo.Invoice
(
    InvoiceID INT IDENTITY(1, 1) PRIMARY KEY,
    CustomerID INT FOREIGN KEY REFERENCES dbo.Customer(CustomerID),
    InvoiceStatus NVARCHAR(50) NOT NULL,
    InvoiceStatusID AS CASE InvoiceStatus 
                         WHEN 'Sent' THEN 1 
                         WHEN 'Complete' THEN 2
                         WHEN 'Received' THEN 3
                       END
)
GO

--INDEX
CREATE NONCLUSTERED INDEX IX_Invoice ON Invoice
(
    CustomerID ASC
)
INCLUDE
(
    InvoiceStatusID
)
GO

私はそれがリーフレベルで保存されていることを理解していますが、値が永続化されていない場合、どのように保存されますか?インデックスは、この状況でSQL Serverがこれらの行を見つけるのにどのように役立ちますか?

どんな助けも大歓迎です、

どうもありがとう、

編集:

これに答えてくれたBrent&Aaronに感謝します これはPasteThePlanです 彼らが説明したことを明確に示しています。

10
Uberzen1

SQL Serverが計算フィールドにインデックスを作成すると、計算フィールドはその時点でディスクに書き込まれますが、そのインデックスの8Kページにのみ書き込まれます。 SQL Serverは、クラスター化インデックスを読み取るときにInvoiceStatusIDを計算できます。そのデータをクラスター化インデックスに書き込む必要はありません。

Dbo.Invoiceの行を削除/更新/挿入すると、インデックスのデータは最新の状態に保たれます。 (InvoiceStatusが変更されると、SQL ServerはIX_Invoiceも更新することを認識します。)

これを実際に確認する最良の方法は、実際にそれを実行することです。これらのオブジェクトを作成し、InvoiceStatusIDフィールドを変更する更新を実行します。インデックスの更新が行われている場所を確認したい場合は、実行計画を投稿します(PasteThePlan.comがこれに役立ちます)。

11
Brent Ozar

インデックス付きの非永続計算列の値は、tableのデータページに永続化されませんが、index。 0、1、または複数のインデックスで永続化されているかどうかに関係なく、テーブルに永続化されません。

ブレントの説明を説明するために、例を挙げて、行を挿入しましょう。

INSERT dbo.Invoice(CustomerID, InvoiceStatus) VALUES(1,N'Sent');

今、インデックスページを見てみましょう:

DBCC TRACEON(3604, -1);
DBCC IND(N'dbname', N'dbo.Invoice', 2);

(明らかにdbnameを変更してください。あなたの場合、インデックスIDは2ではないかもしれません。)

出力(あなたは確かに異なります):

enter image description here

最後に、ページでPageTypeを調べます。

DBCC PAGE(7, 1, 584, 3);

(データベースIDと一致するように7を変更する必要がある可能性が高く、複数のデータファイルがある場合は、最初の結果のPageFIDと一致するように2番目の引数を変更する必要がある場合があります。)

出力:

enter image description here

それはインデックスページにあります。

8
Aaron Bertrand

計算列の属性PERSISTEDは、値がtable(クラスター化インデックスまたはヒープ)に保持されるかどうかに関係し、値はインデックスに保持されます。

CREATE INDEX には、計算された列とインデックスに関する制限の要件があります。

確定的で正確または不正確な計算列を含めることができます。image、ntext、text、varchar(max)、nvarchar( max)、varbinary(max)、およびxmlデータ型は、計算された列のデータ型が含まれる列として許容される限り、非キー列に含めることができます。詳細については、計算列のインデックスを参照してください。

計算列が永続化されるかどうかに制限はありません。

さらに(含まれるのではなく、インデックスの主要部分の計算列について):

インデックスは計算列に作成できます。さらに、計算列にはプロパティPERSISTEDを設定できます。つまり、データベースエンジンは計算された値をテーブルに格納し、計算された列が依存する他の列が更新されたときにそれらを更新します。データベースエンジンは、列にインデックスを作成するとき、およびインデックスがクエリで参照されるときに、これらの永続化された値を使用します。

計算列にインデックスを付けるには、計算列が決定的で正確でなければなりません。ただし、PERSISTEDプロパティを使用すると、インデックス付け可能な計算列のタイプが拡張され、次のものが含まれます。

...

7
ypercubeᵀᴹ