База данных SQL Server с кластеризованным GUID PKs - переключает кластерный индекс или переключает на последовательный (расческа) GUID?

У нас есть база данных, в которой всеми PKs являются GUID, и большинство PKs является также кластерным индексом для таблицы. Мы знаем, что это плохо (из-за случайной природы GUID). Так, кажется, что существует в основном две опции здесь (за исключением вывода GUID как PKs в целом, который мы не можем сделать (по крайней мере, не в это время)).

  • Мы могли изменить алгоритм поколения GUID на, например, тот, который NHibernate использует, как детализировано в этом сообщении, или
  • мы, для таблиц, которые являются объектом интенсивного использования, могли измениться на другой кластерный индекс, например, столбец IDENTITY, и сохранить "случайные" GUID как PKs.

Действительно ли возможно дать какие-либо общие рекомендации в таком сценарии?

Рассматриваемое приложение имеет 500 + таблицы, самая большая в настоящее время приблизительно в 1,5 миллионах строк, несколько таблиц приблизительно 500 000 строк и остальные значительно ниже (большинство из них значительно ниже 10K).

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

Спасибо!

5
задан Community 23 May 2017 в 11:47
поделиться

2 ответа

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

Если вы пойдете по маршруту Identity для кластеризованного первичного ключа, а затем просто сделаете индекс в своем столбце guid, вы все равно получите большую фрагментацию в своем индексе guid. Однако тот факт, что таблица больше не будет фрагментироваться, будет огромным преимуществом.

Наконец, я знаю, что вы сказали, что пока не можете этого сделать, но, если вам вообще не НУЖНО использовать guids в качестве индекса, вы устраните все эти проблемы.

3
ответ дан 13 December 2019 в 22:04
поделиться

Мое мнение однозначно: используйте INT IDENTITY для ключа кластеризации. Это, безусловно, лучший и наиболее оптимальный ключ кластеризации, потому что он:

  • маленький
  • стабильный (никогда не должен меняться)
  • уникальный
  • постоянно увеличивающийся

Последовательные GUID определенно намного лучше, чем обычные случайные GUID. , но он по-прежнему в четыре раза больше, чем INT (16 против 4 байтов), и это будет иметь значение, если в вашей таблице много строк, а также много некластеризованных индексов в этой таблице. Ключ кластеризации добавляется к каждому некластеризованному индексу, что значительно увеличивает негативный эффект от размера 16 против 4 байтов. Больше байтов означает больше страниц на диске и в ОЗУ SQL Server и, следовательно, больше дисковых операций ввода-вывода и больше работы для SQL Server.

Вы можете определенно сохранить GUID в качестве первичного ключа, где это необходимо, но в этом случае я настоятельно рекомендую добавить отдельный INT IDENTITY в эту таблицу и сделать этот INT ключом кластеризации.Я сам проделал это с несколькими большими таблицами, и результаты поразительны - фрагментация таблиц снизилась с 99 и более процентов до нескольких процентов, а производительность стала намного лучше.

Ознакомьтесь с прекрасной серией статей Кимберли Трипп о том, почему идентификаторы GUID плохи в качестве ключей кластеризации в SQL Server здесь:

Марк

7
ответ дан 13 December 2019 в 22:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: