Mengapa menambahkan kolom NOT NULL dengan kendala standar sesaat?

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

Ketika saya menjalankan skrip pengujian ini, ALTERdengan UPDATEmembutuhkan waktu 6 detik yang bisa dimengerti.

Namun, ALTERdengan DEFAULT NOT NULLmengeksekusi instan bahkan di atas meja yang jauh lebih besar. Apakah ada penjelasan mengapa ini instan? Pada disk fisik, data masih perlu ditulis ke semua baris, kan?

Saya mencoba melihat SET STATISTICS IO ONdan rencana Query, tetapi sepertinya itu tidak tersedia untuk operasi DDL.

Akash
sumber

Jawaban:

23

Ya, menambahkan kolom dengan NOT NULL dan default tidak benar-benar menulis nilai ke semua baris pada saat perubahan, sehingga tidak lagi menjadi operasi ukuran data. Ketika Anda memilih dari tabel, kolom sebenarnya terwujud dari sys.system_internals_partition_columns , yang mencegah semua nilai dari harus ditulis (sampai mereka berubah). Perhatikan bahwa ini tidak berfungsi untuk semua tipe data dan memerlukan Edisi Perusahaan.

Remus Rusanu menjelaskan ini secara lebih rinci di sini:

Juga, untuk ALTERsetidaknya, kami masih tidak dapat menunjukkan kepada Anda sebuah rencana karena SQL Server tidak menghasilkan satu, tetapi untuk melihat I / O, Anda dapat menggunakan SQL Sentry Plan Explorer . * Cuplikan layar ini menunjukkan penambahan kolom, c5 , "online" seperti yang dijelaskan di atas, dan kemudian kolom lain, c6, "offline" karena tipe LOB tidak didukung. Anda dapat melihat I / O sebagian besar dinyatakan sebagai membaca daripada menulis, tetapi yang lebih jelas adalah (tidak valid!) Yang UPDATEterkait dengan perubahan offline.

I / O untuk perubahan online vs. offline

Jika Anda tidak memiliki Edisi Perusahaan, kedua pernyataan akan memiliki UPDATElampiran sekunder (dan bacaan terkait). (Dan jika Anda menggunakan versi gratis Plan Explorer, yang tidak mendapatkan tumpukan panggilan permintaan penuh, Anda tidak akan melihat yang di atas - Anda hanya akan melihat pohon pernyataan yang kosong. Versi berbayar diperlukan untuk melihat permintaan penuh panggil tumpukan.)

Perhatikan bahwa SQL Server akan menghasilkan perkiraan paket, tetapi itu tidak terlalu berguna. Sama sekali. Dan rencana taksiran untuk perubahan online identik dengan rencana taksiran perubahan offline.

Rencanakan diagram untuk perubahan online

* Penafian: Saya bekerja untuk SQL Sentry.

Aaron Bertrand
sumber
4
+1: esp. untuk "Edisi Perusahaan". Saya selalu bertanya-tanya mengapa itu tidak berhasil di beberapa situs pelanggan saya ...
RBarryYoung