У меня есть таблица с миллионами строк и столбцом, который допускает значения NULL. Однако ни одна строка в настоящее время не имеет значения NULL для этого столбца (я могу достаточно быстро это проверить с помощью запроса). Однако, когда я выполняю команду
ALTER TABLE MyTable ALTER COLUMN MyColumn BIGINT NOT NULL;
запрос длится вечно условно говоря. На самом деле это занимает от 10 до 20 минут, более чем вдвое дольше, чем добавление проверочного ограничения. Есть ли способ мгновенно обновить метаданные таблицы для этого столбца, тем более что я знаю, что ни одна строка не имеет значения NULL для этого столбца?
sql-server-2008
null
alter-table
Джозеф Дейгл
источник
источник
Sch-M
блокировки, когда он «навсегда». Вы смотрели, чтобы увидеть, ожидал ли он или занят?Ответы:
Ответ @ ypercube справляется с этим частично только из-за изменения метаданных.
Добавление ограничения
NOCHECK
означает, что для его проверки не нужно читать строки, и если вы начинаете с позиции, в которой столбец не содержитNULL
значений (и если вы знаете, что между проверкой и добавлением ограничения не будет добавлено ни одной), поскольку ограничение предотвращаетNULL
создание значений из будущегоINSERT
илиUPDATE
операций, это будет работать.Однако добавление ограничения может повлиять на одновременные транзакции.
ALTER TABLE
Нужно будет приобрестиSch-M
замок первым. Пока он ожидает этого, все другие обращения к таблице будут заблокированы, как описано здесь .Однако после того, как
Sch-M
блокировка получена, операция должна быть довольно быстрой.Одна из проблем заключается в том, что даже если вы знаете, что в столбце фактически нет
NULL
s, оптимизатор запросов не доверяет ограничению, что означает, что планы могут быть неоптимальными.Сравните это с более простым
Одна из возможных проблем, с которой вы можете столкнуться при изменении определения столбца таким образом, заключается в том, что он не только должен прочитать все строки, чтобы убедиться, что они удовлетворяют условию, но также может в конечном итоге выполнить записанные обновления строк .
Возможно, на полпути можно добавить ограничение проверки
WITH CHECK
. Это будет медленнее, чемWITH NOCHECK
нужно для чтения всех строк, но это позволяет оптимизатору запросов дать более простой план в запросе выше, и это должно избежать возможной проблемы с записанными обновлениями.источник
Вместо изменения столбца вы можете добавить
CHECK
ограничение таблицы сNOCHECK
параметром:источник
NULL
но не смогут использоваться оптимизатором запросов.ALTER COLUMN
после полученияSch-M
блокировки, это вообще не требует сканирования строк). Просто отметив, что это не совсем то же самое (например, если использовать вNOT IN
запросе, план будет более сложным)