Ответ @ ypercube справляется с этим частично только из-за изменения метаданных.
Добавление ограничения NOCHECKозначает, что для его проверки не нужно читать строки, и если вы начинаете с позиции, в которой столбец не содержит NULLзначений (и если вы знаете, что между проверкой и добавлением ограничения не будет добавлено ни одной), поскольку ограничение предотвращает NULLсоздание значений из будущего INSERTили UPDATEопераций, это будет работать.
Однако добавление ограничения может повлиять на одновременные транзакции. ALTER TABLEНужно будет приобрести Sch-Mзамок первым. Пока он ожидает этого, все другие обращения к таблице будут заблокированы, как описано здесь .
Однако после того, как Sch-Mблокировка получена, операция должна быть довольно быстрой.
Одна из проблем заключается в том, что даже если вы знаете, что в столбце фактически нет NULLs, оптимизатор запросов не доверяет ограничению, что означает, что планы могут быть неоптимальными.
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нужно для чтения всех строк, но это позволяет оптимизатору запросов дать более простой план в запросе выше, и это должно избежать возможной проблемы с записанными обновлениями.