Использование идентификаторов GUID в первичных ключах / Кластеризованных индексах
-
16-09-2019 - |
Вопрос
Я довольно хорошо разбираюсь в производительности SQL server, но мне постоянно приходится оспаривать идею о том, что GUID следует использовать в качестве типа по умолчанию для первичных ключей Clusterd.
Предполагая, что таблица имеет довольно низкое количество вставок в день (5000 + / - строк в день), с какими проблемами производительности мы могли бы столкнуться?Как разделение страниц повлияет на эффективность поиска?Как часто я должен переиндексировать (или я должен дефрагментировать)?На какое значение я должен установить коэффициенты заполнения (100, 90, 80 и т.д.)?
Что, если бы я вставлял 1 000 000 строк в день?
Я заранее приношу извинения за все вопросы, но я хочу получить некоторую резервную копию для того, чтобы не использовать GUID по умолчанию для PKS.Однако я полностью открыт для того, чтобы мое мнение изменилось благодаря обширным знаниям из базы пользователей StackOverflow.
Решение
Если вы выполняете какой-либо объем, GUID крайне плохи как PK bad, если вы не используете последовательные направляющие, по точным причинам, которые вы описываете. Фрагментация страницы является серьезной:
Average Average
Fragmentation Fragment Fragment Page Average
Type in Percent Count Size Count Space Used
id 4.35 7 16.43 115 99.89
newidguid 98.77 162 1 162 70.90
newsequentualid 4.35 7 16.43 115 99.89
И как это сравнение между идентификаторами GUID и целыми числами отображается:
Тест1 вызвал огромное количество разбиений страниц и имел плотность сканирования около 12% когда я запустил DBCC SHOWCONTIG после завершения вставок.Таблица Test2 имела плотность сканирования около 98%
Однако, если ваша громкость очень мала, это просто не имеет большого значения.
Если вам действительно нужен глобально уникальный идентификатор, но у вас большой объем (и вы не можете использовать последовательные идентификаторы), просто поместите GUID в индексированный столбец.
Другие советы
Недостатки использования GUID в качестве первичного ключа:
- Отсутствие осмысленного упорядочивания означает, что индексация не повышает производительность, как это происходит с целым числом.
- Размер GUID 16 байт по сравнению с 2, 4 или 8 байтами для целого числа.
- Людям очень трудно запомнить, поэтому в качестве идентификатора ссылки не годится.
Преимущества:
- Разрешить не поддающиеся угадыванию первичные ключи, которые, следовательно, могут быть менее опасными при отображении в строке запроса веб-страницы или в приложении.
- Полезно в базах данных, которые не предоставляют автоматическое увеличение или идентификационный тип данных.
- Полезно, когда вам нужно объединить данные между двумя разрозненными источниками данных на разных платформах или средах.
Я думал, что решение о том, использовать ли GUID, было довольно простым, но, возможно, я не знаю о других проблемах.
При таком малом количестве вставок в день я сомневаюсь, что разделение страниц должно быть существенным фактором.Реальный вопрос заключается в том, как 5000 сравнивается с существующим количеством строк, поскольку это была бы основная информация, необходимая для принятия решения о соответствующем начальном коэффициенте заполнения для разделения.
Тем не менее, лично я не большой поклонник GUID.Я понимаю, что они могут хорошо служить в некоторых контекстах, но во многих случаях они просто "мешают" [эффективности, простоте использования, ...]
Я нахожу следующие вопросы полезными, чтобы сузить круг при принятии решения о том, следует ли использовать GUID или нет.
- Будет ли ПК распространен / опубликован ?(т.е.будет ли он использоваться помимо его внутреннего использования в SQL, будут ли приложения нуждаться в этих ключах несколько постоянным образом?Будут ли пользователи каким-то образом видеть эти ключи?
- Можно ли использовать PK для объединения разрозненных источников данных ?
- Есть ли в таблице первичный - возможно, составной - составленный из столбцов в данных ?Каков размер этого возможного этого ключа
- Как сортируются первичные ключи?Если составные, являются ли первые несколько столбцов выборочными ?
Использование guid (если только это не последовательный GUID) в качестве кластеризованного индекса приведет к снижению производительности вставки.Поскольку физический макет таблицы выровнен в соответствии с кластеризованным индексом, использование guid, который имеет случайный порядок следования, приведет к серьезной фрагментации таблицы.Если вы хотите использовать guid в качестве PK / кластеризованного индекса, это должен быть последовательный guid, использующий функцию newsequentialid() в sql server.Это гарантирует, что сгенерированные идентификаторы guid упорядочены последовательно и предотвратит фрагментацию.