@ ypercube'un cevabı bunu yalnızca meta veri değişikliği olarak kısmen yönetir.
Kısıtlama eklemek, NOCHECK
doğrulamak için hiçbir satırın okunmayacağı anlamına gelir ve sütunun NULL
değer içermediği bir konumdan başlıyorsanız (ve kısıtlamayı denetleme ve ekleme arasında hiçbiri eklenmeyeceğini biliyorsanız), kısıtlama NULL
gelecekteki INSERT
veya UPDATE
işlemlerden yaratılan değerlerin önüne geçtiği için bu işe yarar.
Bununla birlikte, kısıtlamanın eklenmesinin eşzamanlı işlemler üzerinde hala bir etkisi olabilir. ALTER TABLE
Bir kazanmak gerekir Sch-M
ilk kilidi. Bunu beklerken, diğer tüm tablo erişimleri burada açıklandığı gibi engellenecektir .
Sch-M
Kilit alındıktan sonra işlem oldukça hızlı olmalıdır.
Bununla ilgili bir sorun, sütunun aslında NULL
s olmadığını bilmenize rağmen , kısıtlamanın sorgu optimize edici tarafından güvenilmemesidir, bu da planların alt optimal olabileceği anlamına gelir.
CREATE TABLE T (X INT NULL)
INSERT INTO T
SELECT ROW_NUMBER() OVER (ORDER BY @@SPID)
FROM master..spt_values
ALTER TABLE T WITH NOCHECK
ADD CONSTRAINT X_NOT_NULL
CHECK (X IS NOT NULL) ;
SELECT *
FROM T
WHERE X NOT IN (SELECT X FROM T)
Bunu daha basit ile karşılaştırın
ALTER TABLE T ALTER COLUMN X INT NOT NULL
SELECT *
FROM T
WHERE X NOT IN (SELECT X FROM T)
Sütun tanımını bu şekilde değiştirmekle karşılaşabileceğiniz olası bir sorun, yalnızca koşulu karşıladıklarını doğrulamak için tüm satırları okuması değil, aynı zamanda satırlara kaydedilmiş güncellemeler gerçekleştirebilmesidir .
Muhtemel bir yarım ev çek kısıtlaması eklemek olabilir WITH CHECK
. Bu, WITH NOCHECK
tüm satırları okuması gerektiğinden daha yavaş olacaktır, ancak sorgu optimize edicisinin yukarıdaki sorguda daha basit bir plan vermesine izin verir ve olası günlüğe kaydedilmiş güncellemeler sorununu önlemelidir.
NULL
ancak sorgu optimize edici tarafından kullanılamayan gelecekteki güncellemeleri veya eklemeleri önleyecektir .