@ ypercube відповідь частково керує цією зміною лише метадані.
Додавання обмеження NOCHECK
означає, що для його перевірки не потрібно читати жодних рядків, і якщо ви починаєте з позиції, коли стовпець не містить NULL
значень (і якщо ви знаєте, жодного не буде додано між перевіркою та додаванням обмеження), оскільки обмеження не дозволяє NULL
створювати значення з майбутніх INSERT
чи UPDATE
операцій, це буде спрацьовувати.
Додавання обмеження все ще може впливати на одночасні транзакції. ALTER TABLE
Потрібно буде придбати Sch-M
замок першим. Поки він чекає цього, всі інші доступу до таблиці будуть заблоковані, як описано тут .
Після Sch-M
придбання блокування операція повинна бути досить швидкою.
Одна з проблем з цим полягає в тому, що навіть якщо ви знаєте, що стовпець насправді не має NULL
, обмеження не довіряється оптимізатору запитів, що означає, що плани можуть бути недостатньо оптимальними.
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)
Порівняйте це з більш простим
ALTER TABLE T ALTER COLUMN X INT NOT NULL
SELECT *
FROM T
WHERE X NOT IN (SELECT X FROM T)
Однією з можливих проблем, з якою ви можете зіткнутися із зміною визначення стовпця таким чином, є те, що йому потрібно не тільки прочитати всі рядки, щоб переконатися, що вони відповідають умові, але і може в кінцевому підсумку виконати фактично зареєстровані оновлення рядків .
Можливим будинком на півдорозі може бути додавання обмеження чека WITH CHECK
. Це буде повільніше, ніж WITH NOCHECK
потрібно для читання всіх рядків, але це дає змогу оптимізатору запитів дати простіший план у вищезазначеному запиті, і він повинен уникати можливих проблем з оновленими оновленнями.