Во время недавней конференции SQLRally была интересная дискуссия о поведении SQL Server в отношении статистики на столбцах UNIQUEIDENTIFIER. Эта статья призвана прояснить эту тему.
Давайте начнем с рассмотрения простого определения таблицы с столбцом UNIQUEIDENTIFIER в качестве первичного ключа:
CREATE TABLE CustomersTableGuid ( ID UNIQUEIDENTIFIER NOT NULL PRIMARY KEY, FirstName VARCHAR(50), LastName VARCHAR(50) )
Когда на столбце UNIQUEIDENTIFIER накладывается ограничение первичного ключа, SQL Server генерирует уникальный кластеризованный индекс в фоновом режиме. У этого кластеризованного индекса есть подлежащий объект Statistics, который описывает распределение данных в этом столбце.
Теперь давайте вставим 1 миллион строк в эту таблицу:
DECLARE @i INT = 0
WHILE (@i < 1000000)
BEGIN
INSERT INTO CustomersTableGuid (ID, FirstName, LastName)
VALUES (NEWID(), 'John', 'Doe')
SET @i = @i + 1
END
Затем мы обновляем статистику на этой таблице с помощью FULLSCAN. FULLSCAN означает, что SQL Server сканирует все подлежащие данные для обновления объекта статистики:
UPDATE STATISTICS CustomersTableGuid WITH FULLSCAN
Однако, когда мы смотрим на объект Statistics сейчас, мы видим, что SQL Server сгенерировал только 3 шага в гистограмме. Это удивительно, учитывая, что все 1 миллион строк были отобраны во время обновления статистики:
Но когда мы обновляем объект Statistics с меньшим интервалом выборки, все начинает меняться:
UPDATE STATISTICS CustomersTableGuid WITH SAMPLE 50 PERCENT
Теперь, когда мы смотрим на гистограмму, мы видим, что у нас есть много разных шагов:
Это поведение может быть довольно удивительным, но важно понимать, что пока значения в столбце UNIQUEIDENTIFIER являются уникальными, не должно возникать проблем с производительностью. Строка AVG_RANGE_ROW все равно делает правильную оценку 1 строки для огромного количества пробелов в гистограмме.
Так что, работая со столбцами UNIQUEIDENTIFIER в вашем проекте базы данных, имейте это поведение в виду. Всегда полезно анализировать и понимать статистику на ваших столбцах, чтобы обеспечить оптимальную производительность.
Спасибо за чтение!
– Ваш автор блога о SQL Server