Ключи GUID: идентификатор и кластерный индекс
Оцените размер GUID, случайные вставки и конкуренцию последовательных ключей, сравнив публичный GUID с узким внутренним ключом.
Глобально уникальный идентификатор может подходить для публичного API, не являясь лучшим кластерным ключом. Публичная идентичность помогает интеграции и распределённой записи. Кластеризация влияет на расположение строк, размер индексов и вставки внутри таблицы. Это разные решения.
Какую стоимость измерять
uniqueidentifier занимает шестнадцать байтов, bigint восемь. В кластерной rowstore-таблице кластерный ключ также служит указателем строки в некластерных индексах. Поэтому широкая идентичность увеличивает хранение за пределами основной таблицы. Эффект зависит от индексов, сжатия и формы строк.
Случайные NEWID распределяют вставки по пространству ключей. Заполненная целевая страница может потребовать дополнительной работы и разделения. Растущий ключ, наоборот, способен сосредоточить конкуренцию на последней странице. Распределение и концентрация активности имеют разные последствия; универсального победителя нет.
Пример отделяет узкий внутренний ключ от уникального публичного GUID. Используйте учебную базу. Это вариант для измерения, а не указание мигрировать все таблицы.
CREATE TABLE dbo.KeyDesignDemo
( InternalId bigint IDENTITY(1,1) NOT NULL
CONSTRAINT PK_KeyDesignDemo PRIMARY KEY CLUSTERED,
PublicId uniqueidentifier NOT NULL DEFAULT NEWID(),
CreatedAt datetime2(3) NOT NULL DEFAULT SYSUTCDATETIME(),
Payload nvarchar(200) NOT NULL,
CONSTRAINT UQ_KeyDesignDemo_PublicId UNIQUE NONCLUSTERED(PublicId)
);
INSERT dbo.KeyDesignDemo(Payload) VALUES(N'example');
SELECT InternalId,PublicId FROM dbo.KeyDesignDemo;
Поиск PublicId использует уникальный некластерный индекс и может дополнительно обращаться за Payload. Если нужен только InternalId, дополнительное обращение может не потребоваться. Включайте поля только при оправданном выигрыше чтения относительно хранения и записи.
Что дают последовательные GUID
NEWSEQUENTIALID уменьшает случайность вставки при использовании в default столбца uniqueidentifier. Это не универсальная скалярная замена NEWID. Порядок после перезапусков или смены машины нельзя считать бизнес-часами. Идентификатор также не должен служить секретом авторизации.
Последовательность не уменьшает ширину шестнадцати байтов. Она может перенести давление в горячую область вставки. Различайте ожидания защёлок страниц, транзакционные блокировки и ожидания диска. Изменение против фрагментации необязательно устраняет конкуренцию последней страницы.
Fill factor резервирует место при создании или перестроении, но не поддерживает этот процент постоянно свободным. Уменьшение может сократить некоторые разделения и одновременно увеличить страницы и чтения. Выбирайте значение по измеренному росту, а не для всех индексов сразу.
Проверка всей нагрузки
Измеряйте конкурентные вставки, публичные поиски, внутренние соединения и диапазонные отчёты. Сравнивайте полный размер индексов, журнал, работу страниц, пропускную способность и крайние задержки. Быстрые вставки при дорогих частых поисках могут ухудшить приложение в целом.
Смена существующего кластерного ключа является структурной миграцией. Найдите внешние ключи, зависимые индексы, требования репликации и предположения приложения. Добавление InternalId не перенаправляет существующие GUID-ссылки. Явно определите, какие дочерние таблицы сохраняют GUID, а какие используют внутренний ключ.
Для распределённых писателей задайте место генерации и объединение данных. Локальная identity сама по себе не глобально уникальна. Внешний GUID может сохранить интеграционный договор, пока внутренний ключ остаётся локальным.
Проверьте переключение узлов, массовые загрузки, удаления с новыми вставками и данные больше буферного пула. Права доступа остаются обязательными даже для трудно угадываемых ключей. Измерьте обслуживание дополнительного индекса в разделённой схеме и стоимость соединений дочерних таблиц. Она может превысить экономию основной таблицы. Сравнивайте одинаковые объёмы и сценарии чтения, включая типичные размеры пакетов записи. После миграции отдельно проверьте соответствие внешних и внутренних идентификаторов. Итогом должна стать подтверждённая нагрузкой стратегия ключей, а не утверждение, что GUID всегда плох или последовательность всегда быстрее.
Для измерений сохраняйте версии схемы и конфигурации вместе с результатами. Иначе последующий рост индексов или добавление нового пути записи может сделать прежнее сравнение неприменимым.
Техническая документация: Microsoft Learn: Index design · Microsoft Learn: NEWSEQUENTIALID.