NewSequentialId в кластерном индексе UniqueIdentifier - PullRequest
5 голосов
/ 04 августа 2011

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

(ПРИМЕЧАНИЕ. Я не хочу обсуждать плюсы и минусы использования 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} * 1 025 * {35729A0C-F016-4645-ABA9-B098D2003E65}
{35729A0C-F016-4645-ABA9-B098D2003E66} * * 1 027

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

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

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

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

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

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

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

1 Ответ

1 голос
/ 04 августа 2011

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

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

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

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

Kim
Tripp в
Блог

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

...