デフォルトの制約を持つNOT NULL列を瞬時に追加するのはなぜですか?


16
CREATE TABLE TestTab (ID INT IDENTITY(1,1), st nvarchar(100))

INSERT INTO TestTab (st) values ('a')
INSERT INTO TestTab (st) values ('b')
INSERT INTO TestTab (st) values ('c')
INSERT INTO TestTab (st) values ('d')
INSERT INTO TestTab (st) values ('e')

INSERT INTO TestTab (st) SELECT TOP 10000 st from testtab
GO 30

ALTER TABLE TestTab ADD newcol nvarchar(10) DEFAULT 'newcol'
UPDATE TestTab SET newcol = 'newcol'  --6 sec
ALTER TABLE TestTab ADD newcol1 nvarchar(10) DEFAULT 'newcol1' NOT NULL

DROP TABLE TestTab

このテストスクリプトを実行すると、ALTERwith UPDATEは6秒かかります。

ただし、ALTERwithはDEFAULT NOT NULL、はるかに大きなテーブルでも瞬時に実行されます。これが瞬間的である理由について説明はありますか?物理ディスクでは、データをすべての行に書き込む必要がありますか?

SET STATISTICS IO ONクエリプランを見てみましたが、DDL操作に使用できないようです。

回答:


23

はい、NOT NULLおよびデフォルトで列を追加しても、実際には変更時にすべての行に値が書き込まれるわけではないため、データサイズ操作ではなくなりました。テーブルから選択すると、列は実際にはsys.system_internals_partition_columnsからマテリアライズされるため、すべての値を(変更されるまで)書き込む必要がなくなります。これはすべてのデータタイプで機能するわけではなく、Enterprise Editionが必要です。

Remus Rusanuが、これについて詳しく説明します。

また、ALTER少なくとも、SQL Serverはプランを作成しないため、プランを表示することはできませんが、I / Oを確認するには、SQL Sentry Plan Explorerを使用できます。*このスクリーンショットは、列c5の追加を示しています、「オンライン」、およびLOBタイプがサポートされていないため、別の列c6、「オフライン」。I / Oの大部分は書き込みではなく読み取りとして表現されていますが、より重要なことはUPDATE、オフライン変更に関連付けられた(無効な!)

オンラインとオフラインの変更のI / O

Enterprise Editionがない場合、両方のステートメントにセカンダリがUPDATEアタッチされます(および関連する読み取り)。(また、完全なクエリコールスタックを取得できないプランエクスプローラーの無料版を使用する場合、上記は表示されません。空のステートメントツリーが表示されます。完全なクエリを表示するには有料版が必要です。呼び出しスタック。)

SQL Serverは推定プランを作成しますが、あまり有用ではないことに注意してください。まったく。また、オンライン変更の推定計画は、オフライン変更の推定計画と同一です。

オンライン変更の計画図

* 免責事項:私はSQL Sentryで働いています。


4
+1:特に 「Enterprise Edition」の場合。顧客サイトの一部でなぜ機能しなかったのかといつも不思議に思っていました...
RBarryYoung
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.