Увеличьте скорость изменения столбца на большом столе до NON NULL

12

Недавно я добавил битовый столбец, поддерживающий NULL, в таблицу, в которой содержится около 500 миллионов строк. В столбце нет значения по умолчанию, однако для всех вставок указано значение 0 или 1, и я выполнил одноразовую процедуру, чтобы присвоить 0 или 1 всем существующим строкам (обновление строк небольшими партиями). Каждая строка должна иметь 0 или 1 в этом столбце.

Я хочу, чтобы битовый столбец не обнулялся, однако, когда я попытался сделать это через ALTER TABLE t1 ALTER COLUMN c1 bit not null, он начал работать в течение 3 минут, и я остановил его, потому что он блокировал все чтения в таблице, и я подозревал, что это займет много времени, чтобы завершить , Возможно, это не займет много времени, но я не могу рисковать слишком большой недоступностью. Сам откат занял 6 минут.

Есть ли у вас какие-либо предложения о том, как сделать столбец необнуляемым, чтобы он не занял много времени? Кроме того, есть ли способ оценить, сколько времени ALTER TABLE ALTER COLUMNзаймет завершение заявления, которое я начал, а затем отменил?

Я использую SQL Server 2017 Web Edition.

Бен Амада
источник

Ответы:

12

Вместо того, чтобы изменить определение столбца, вы можете добавить, CHECK CONSTRAINTчто не допускает значения NULL для этого столбца. Таблицу все равно нужно будет сканировать, но ей не нужно будет изменять каждую страницу данных, поэтому она должна выполняться намного быстрее. К сожалению, замок Sch-M все еще будет удерживаться во время операции. Одна хитрость заключается в том, чтобы попытаться получить как можно большую часть таблицы в буферный пул, прежде чем пытаться добавить ограничение. Это может сократить время удержания блокировки Sch-M.

Затем вы можете удалить ограничение и изменить определение столбца во время следующего окна обслуживания.

Джо Оббиш
источник
Спасибо Джо за идею. Я почти добавил добавление проверочного ограничения, но в выходные у меня было окно обслуживания, и я смог изменить столбец так, чтобы он не обнулялся. Я не уверен, помогло ли это, но чтобы попытаться получить данные таблицы в буферный пул, перед тем, как сделать столбец необнуляемым, я запустил, SELECT c1, count(*) FROM t1 GROUP BY c1что заняло около 9 минут. Фактическое ALTER TABLE ALTER COLUMNутверждение после этого заняло 25 минут. Не так уж плохо.
Бен Амада
11

Если вы используете Enterprise Edition (EE), то лучшей стратегией, возможно, было бы добавить ее, NOT NULLиспользуя значение по умолчанию 0или 1(в зависимости от того, что является наиболее распространенным).

Это изменение метаданных только в EE . Затем обновите те, которые нужно перевернуть. Это означает, что меньше обновлений и нет необходимости изменять обнуляемость столбцов после завершения. - Мартин-Смит

user126897
источник
Интересно, что я заметил эту функцию на прошлой неделе, когда я тестировал добавление необнуляемого битового столбца со значением по умолчанию к этой же большой таблице на моем локальном компьютере, на котором выполняется версия для разработчиков SQL - столбец был добавлен мгновенно, и я не мог понять, почему , Позже он мне, что это должно быть, потому что редакция разработчика включает функции EE.
Бен Амада
-3

Попробуйте скопировать данные в новую таблицу, затем переименуйте ее. Вы должны позаботиться о любых ограничениях и индексах. Это то, что делает дизайнер таблиц SSMS, когда вы хотите изменить порядок столбцов (например), но вы должны проверить скрипт, чтобы увидеть, есть ли что-то, что выглядит неправильно.

Во время копирования доступ для чтения к исходной таблице не является проблемой, но при наличии любых записей они могут быть заблокированы или не скопированы, в зависимости от уровня изоляции.

Разван Соколь
источник