У нас есть база данных, в которой всеми PKs являются GUID, и большинство PKs является также кластерным индексом для таблицы. Мы знаем, что это плохо (из-за случайной природы GUID). Так, кажется, что существует в основном две опции здесь (за исключением вывода GUID как PKs в целом, который мы не можем сделать (по крайней мере, не в это время)).
Действительно ли возможно дать какие-либо общие рекомендации в таком сценарии?
Рассматриваемое приложение имеет 500 + таблицы, самая большая в настоящее время приблизительно в 1,5 миллионах строк, несколько таблиц приблизительно 500 000 строк и остальные значительно ниже (большинство из них значительно ниже 10K).
Кроме того, приложение уже установлено на нескольких сайтах для клиентов, таким образом, мы должны взять любые возможные отрицательные эффекты для существующего клиента к рассмотрению.
Спасибо!
Если вы можете легко изменить генерацию guid на последовательную генерацию guid, то это, вероятно, ваш вариант быстрого выигрыша. Последовательный гид остановит фрагментацию таблицы, оставаясь при этом вашим кластеризованным индексом. Однако основным недостатком последовательного руководства является то, что они затем становятся предполагаемыми, что часто нежелательно, и в первую очередь используются направляющие.
Если вы пойдете по маршруту Identity для кластеризованного первичного ключа, а затем просто сделаете индекс в своем столбце guid, вы все равно получите большую фрагментацию в своем индексе guid. Однако тот факт, что таблица больше не будет фрагментироваться, будет огромным преимуществом.
Наконец, я знаю, что вы сказали, что пока не можете этого сделать, но, если вам вообще не НУЖНО использовать guids в качестве индекса, вы устраните все эти проблемы.
Мое мнение однозначно: используйте INT IDENTITY для ключа кластеризации. Это, безусловно, лучший и наиболее оптимальный ключ кластеризации, потому что он:
Последовательные GUID определенно намного лучше, чем обычные случайные GUID. , но он по-прежнему в четыре раза больше, чем INT (16 против 4 байтов), и это будет иметь значение, если в вашей таблице много строк, а также много некластеризованных индексов в этой таблице. Ключ кластеризации добавляется к каждому некластеризованному индексу, что значительно увеличивает негативный эффект от размера 16 против 4 байтов. Больше байтов означает больше страниц на диске и в ОЗУ SQL Server и, следовательно, больше дисковых операций ввода-вывода и больше работы для SQL Server.
Вы можете определенно сохранить GUID в качестве первичного ключа, где это необходимо, но в этом случае я настоятельно рекомендую добавить отдельный INT IDENTITY в эту таблицу и сделать этот INT ключом кластеризации.Я сам проделал это с несколькими большими таблицами, и результаты поразительны - фрагментация таблиц снизилась с 99 и более процентов до нескольких процентов, а производительность стала намного лучше.
Ознакомьтесь с прекрасной серией статей Кимберли Трипп о том, почему идентификаторы GUID плохи в качестве ключей кластеризации в SQL Server здесь:
Марк