У нас есть таблица с 2,3B строк в нем. Мы хотели бы изменить столбец с NOT NULL на NULL. Столбец содержится в одном индексе (не кластерный или PK-индекс). Тип данных не меняется (это INT). Просто обнуляемость. Утверждение следующее:
Alter Table dbo.Workflow Alter Column LineId Int NULL
Операция переваливает за 10, прежде чем мы ее остановим (мы даже еще не дали ей завершиться, потому что это операция блокировки и занимала слишком много времени). Вероятно, мы скопируем таблицу на dev-сервер, чтобы проверить, сколько времени на самом деле это займет. Но мне любопытно, если кто-нибудь знает, что SQL Server делает скрытно при конвертации из NOT NULL в NULL? Кроме того, нужно ли перестраивать затронутые индексы? Сгенерированный план запроса не указывает, что происходит.
Рассматриваемая таблица сгруппирована (не куча).
источник
Ответы:
Как упомянуто @Souplex в комментариях, одно из возможных объяснений может быть, если этот столбец является первым
NULL
доступным столбцом в некластеризованном индексе, в котором он участвует.Для следующей настройки
sys.dm_db_index_physical_stats показывает, что некластеризованный индекс
ix
имеет 248 листовых страниц и одну корневую страницу.Типичная строка на листовой странице индекса выглядит так
И в корневой странице
Затем работает ...
возвращенный
Снова проверяя индексный лист, строки теперь выглядят как
и строки на страницах верхнего уровня, как показано ниже.
Каждая строка была обновлена и теперь содержит два байта для счетчика столбцов вместе с другим байтом для NULL_BITMAP.
Из-за дополнительной ширины строки некластеризованный индекс теперь имеет 285 листовых страниц и теперь две страницы промежуточного уровня вместе с корневой страницей.
План выполнения для
выглядит следующим образом
Это создает новую копию индекса, а не обновляет существующую и не требует разделения страниц.
источник
Это определенно пересоздаст некластеризованный индекс, а не только обновит метаданные. Это проверено на SQL 2014 и не должно быть проверено в производственной системе:
А теперь самое интересное:
Это даст нам страницы базы данных, где хранятся таблица и некластерный индекс.
Найдите
PagePID
гдеIndexID
2 иPageType
2, а затем выполните следующее:а потом:
Обратите внимание, что в заголовке есть нулевое растровое изображение:
Теперь давайте сделаем:
Если вы действительно нетерпеливы, вы можете попробовать запустить
dbcc page
команду еще раз, но она не удастся, поэтому давайте еще раз проверим распределениеDBCC IND (0, z, -1)
. Страница переместится как по волшебству.Таким образом, изменение обнуляемости столбца повлияет на хранение некластеризованных индексов, которые охватывают этот столбец, поскольку метаданные необходимо обновлять, и вам не нужно будет впоследствии перестраивать индексы.
Многие
ALTER TABLE ... ALTER COLUMN ...
операции могут быть выполнены,ONLINE
начиная с SQL Server 2016, но:источник