8.11.25

Три мифа о NULL bitmap

Автор: Paul Randal, A SQL Server DBA myth a day: (6/30) three null bitmap myths

NULL bitmap (NULL‑битовая карта) отслеживает, какие столбцы в записи имеют значение NULL, а какие нет. Она существует как оптимизация производительности, позволяющая движку хранения не загружать целиком всю запись в процессор, когда в списке SELECT есть столбцы со значениями NULL, — тем самым уменьшается число проверяющих операций в строках кеша процессора (см. ссылку с подробностями о работе кешей памяти CPU и протоколе MESI). Разберём три распространённых мифа:

Миф №6a: NULL‑битовая карта присутствует не всегда.

ИСТИНА

NULL‑битовая карта всегда присутствует на уровне данных записей (в кучах или на листовом уровне кластерных индексов) — даже если в таблице нет допускающих NULL столбцов, — за исключением особого случая, когда запись целиком состоит только из столбцов SPARSE со значением NOT NULL. В индексных записях (листовой уровень некластерных индексов и все нелистовые уровни кластерных и некластерных индексов) NULL‑битовая карта присутствует не всегда.

Вот простой скрипт, доказывающий это:

CREATE TABLE [NullTest] ([c1] INT NOT NULL);
CREATE NONCLUSTERED INDEX [NullTest_NC] ON [NullTest] ([c1]);
GO
INSERT INTO [NullTest] VALUES (1);
GO
EXEC sp_allocationMetadata N'NullTest';
GO

Скрипт sp_allocationMetadata можно взять из моей статьи «Inside The Storage Engine: sp_AllocationMetadata – putting undocumented system catalog views to work».

Возьмите из вывода этого скрипта идентификаторы страниц из столбца First Page. Выполните следующее:

DBCC TRACEON (3604);
DBCC PAGE (foo, 1, 152, 3); -- page ID from SP output where Index ID = 0
DBCC PAGE (foo, 1, 154, 1); -- page ID from SP output where Index ID = 2
GO

Фрагмент вывода первой команды DBCC PAGE для записи данных кучи:

Slot 0 Offset 0x60 Length 11
Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP
Memory Dump @0x685DC060

Фрагмент вывода второй команды DBCC PAGE для записи некластерного индекса:

Slot 0, Offset 0x60, Length 13, DumpStyle BYTE
Record Type = INDEX_RECORD           Record Attributes = No null bitmap
Memory Dump @0x685DC060

Миф №6b: NULL‑битовая карта содержит биты только для столбцов, допускающих NULL.

ЛОЖЬ

Когда NULL‑битовая карта присутствует, она содержит биты для всех столбцов записи, плюс «заполняющие» биты для несуществующих столбцов, чтобы довести размер карты до целого числа байтов. Этот миф я уже опровергал в развёрнутой статье — см. «Заблуждения вокруг размера null bitmap».

Миф №6c: Добавление ещё одного столбца в таблицу всегда немедленно вызывает операцию, затрагивающую весь объём данных.

ЛОЖЬ

Операция «size-of-data» (то есть модификация каждой строки таблицы) при добавлении столбца действительно происходит только в следующих случаях:

  • Новый столбец имеет ненулевое значение по умолчанию и не допускает NULL.
  • Новый столбец имеет ненулевое значение по умолчанию, допускает NULL, и вы используете SQL Server 2008 R2 или более раннюю версию.

Во всех остальных случаях Storage Engine «помнит», что появились один или несколько дополнительных столбцов, которые фактически могут отсутствовать в самих записях. Чуть подробнее это объясняется в заметке «Misconceptions around adding columns to a table».



 

Комментариев нет:

Отправить комментарий