Neden bir varsayılan kısıtlama anlık bir NOT NULL sütunu ekliyor?


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

Bu test komut dosyasını yürüttüğümde, ALTERile UPDATEanlaşılabilir olan 6 saniye sürer.

Ancak, ALTERile DEFAULT NOT NULLçok daha büyük bir tablo üzerinde bile anında yürütür. Bunun neden anlık olduğuna dair herhangi bir açıklama var mı? Fiziksel diskte, verilerin hala tüm satırlara yazılması gerekiyor, değil mi?

Ben denedim SET STATISTICS IO ONve Sorgu planı, ancak bu DDL işlemleri için kullanılabilir görünmüyor.

Yanıtlar:


23

Evet, NOT NULL ve default olan bir sütun eklenmesi, değerleri değiştirme anında tüm satırlara gerçekten yazmaz, bu nedenle artık bir veri boyutu işlemi değildir. Tablodan seçim yaptığınızda, sütunlar aslında sys.system_internals_partition_columns öğesinden oluşturulur , bu da tüm değerlerin yazılmasını (değiştirilene kadar) önler. Bunun tüm veri türleri için çalışmadığını ve Enterprise Edition gerektirdiğini unutmayın.

Remus Rusanu bunu burada daha ayrıntılı olarak açıklıyor:

Ayrıca, ALTER en azından SQL Server bir tane üretmediği için size hala bir plan gösteremiyoruz, ancak G / Ç'yi görmek için SQL Sentry Plan Explorer'ı kullanabilirsiniz . * Bu ekran görüntüsü, c5, , "çevrimiçi" ve yukarıda açıklandığı gibi başka bir sütun olan c6, "çevrimdışı" çünkü LOB türleri desteklenmez. I / O'nun çoğunlukla yazma yerine okuma olarak ifade edildiğini görebilirsiniz, ancak daha fazla söylemek UPDATEçevrimdışı değiştirmeyle ilişkili (geçersiz!) .

Çevrimiçi ve çevrimdışı alter için G / Ç

Enterprise Edition'a sahip değilseniz, her iki ifadede de ikincil UPDATEek (ve ilişkili okumalar) bulunur. (Ve tam sorgu çağrısı yığınını almayan Plan Explorer'ın ücretsiz sürümünü kullanırsanız, yukarıdakileri görmezsiniz - sadece boş bir ifade ağacı görürsünüz. Tam sorguyu görmek için ücretli bir sürüm gerekir çağrı yığını.)

SQL Server üretecek unutmayın bir tahmin plan , ancak çok kullanışlı değildir. Hiç. Çevrimiçi bir değişiklik için tahmini plan, çevrimdışı bir değişiklik için tahmini planla aynıdır.

Online değişim için plan diyagramı

* Yasal Uyarı: SQL Sentry için çalışıyorum.


4
+1: esp. "Enterprise Edition" için. Her zaman neden bazı müşteri sitelerimde işe yaramadığını merak ettim ...
RBarryYoung
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.