NewSequentialId в кластерном индексе UniqueIdentifier

Я работаю над стандартами базы данных для новой базы данных, которую начинает моя компания. Одна из вещей, которую мы пытаемся определить, - это правила первичного ключа и кластеризованного индекса по отношению к уникальным идентификаторам.

(ПРИМЕЧАНИЕ. Я не хочу обсуждать плюсы и минусы использования UniqueIdentifier в качестве первичного ключа или кластерного индекса. В Интернете есть тонна информации об этом. Это не то обсуждение.)

Вот сценарий, который меня беспокоит:

Скажем, у меня есть таблица с UniqueIdentifier в качестве кластерного индекса и первичного ключа. Давайте назовем это ColA. Я установил значение по умолчанию для ColA как NewSequentialId().

Используя этот NewSequentialId (), я вставляю три последовательных строки:

{72586AA4-D2C3-440D-A9FE-CC7988DDF065}
{72586AA4-D2C3-440D-A9FE-CC7988DDF066}
{72586AA4-D2C3-440D-A9FE-CC7988DDF067}

Затем я перезагружаю свой сервер. Документы для NewSequentialId говорят, что "после перезапуска Windows GUID может начаться снова с более низкого диапазона, но все еще остается глобально уникальным".

Таким образом, следующая начальная точка может быть ниже, чем предыдущий диапазон.

Поэтому после перезагрузки я вставляю еще 3 значения:

{35729A0C-F016-4645-ABA9-B098D2003E64}
{35729A0C-F016-4645-ABA9-B098D2003E65}
{35729A0C-F016-4645-ABA9-B098D2003E66}

(Я не уверен точно, как guid представлен в базе данных, но давайте предположим, поскольку этот начинается с 3, а предыдущие начинаются с 7, что 3 "меньше", чем 7.)

Когда вы делаете вставку, которая находится в середине кластерного индекса, должно произойти переопределение индекса. (По крайней мере, так сказал мне мой администратор базы данных.) И каждый раз, когда я перезагружаюсь, я рискую, что мой новый диапазон UniqueIdentifier окажется в середине других предыдущих диапазонов.

Итак, мой вопрос: так как следующий набор UniqueIdentifiers будет меньше, чем последний набор, будет ли каждая вставка приводить к перемешиванию моего кластерного индекса?

А если нет, то почему? SQL Server знает, что я использую NewSequentialId? Это как-то компенсирует это?

Если нет, то как он узнает, что я вставлю дальше? Может быть, следующий миллион вставок начнется с 3. Или, может быть, они начнутся с 7. Как он узнает?

Или не знает и просто держит все в порядке. Если это так, то одна перезагрузка может сильно повлиять на производительность. (Что заставляет меня думать, что мне нужен мой собственный NewSequentialId, на который не влияют перезагрузки.) Это правильно? Или есть какая-то магия, о которой я не знаю?

РЕДАКТИРОВАТЬ: GUID как кластерный индекс настоятельно не рекомендуется в моем стандарте. Как я уже говорил выше, есть много причин, по которым это плохая идея. Я пытаюсь выяснить, если это еще одна причина, почему.

1 ответ

Обычно вы будете создавать свои индексы с соответствующими FILL FACTOR оставить пустое место на всех ваших страницах именно для такого сценария. При этом кластеризованный индекс переупорядочивается после заполнения пустого пространства.

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

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

Для полного лечения по теме, нет лучшего источника, чем

Ким
Tripp - х
Блог

Напомним, что когда вы рассматриваете возможность создания собственной функции создания NewSequentialID, у вас, вероятно, есть проблема с дизайном, и вам следует пересмотреть свой план.

Другие вопросы по тегам