Изменение newid() на newsequentialid() в существующей таблице
На данный момент у нас есть несколько таблиц, которые используют newid() для первичного ключа. Это вызывает большое количество фрагментации. Поэтому я хотел бы изменить столбец, чтобы использовать вместо него newsequentialid().
Я предполагаю, что существующие данные останутся довольно фрагментированными, но новые данные будут менее фрагментированными. Это может означать, что мне следует подождать некоторое время, прежде чем менять индекс PK с некластеризованного на кластеризованный.
У меня вопрос, есть ли у кого-нибудь такой опыт? Есть ли что-то, что я упустил из виду, что мне следует быть осторожным?
4 ответа
Если вы переключитесь на последовательные руководства и реорганизуете индекс одновременно, вы устраните фрагментацию. Я не понимаю, почему вы хотите просто подождать, пока фрагментированные ссылки на страницы не перестроятся в непрерывные экстенты.
При этом вы провели какие-либо измерения, чтобы показать, что фрагментация действительно влияет на вашу систему? Если вы просто посмотрите на индекс и увидите, что он "фрагментирован на 75%", это не означает, что это влияет на время доступа. Есть еще много факторов, которые вступают в игру (ожидаемая продолжительность жизни страницы пула буферов, скорость чтения и записи, локальность последовательных операций, параллельность операций и т. Д. И т. Д.). Хотя переход от направляющих к последовательным направляющим обычно безопасен, вы можете по-прежнему создавать проблемы. Например, вы можете увидеть состязание защелок страниц для системы OLTP с интенсивным использованием вставок, поскольку она создает "горячую точку", где накапливаются вставки.
Вы можете подумать об использовании гребенчатых направляющих, в отличие от newsequentialid.
cast(
cast(NewID() as binary(10)) +
cast(GetDate() as binary(6))
as uniqueidentifier)
Направляющие гребенки представляют собой комбинацию чисто случайных направляющих наряду с неслучайностью текущей даты и времени, так что последовательные поколения гребенчатых направляющих расположены рядом друг с другом и, как правило, в порядке возрастания. Направляющие гребенки имеют различные преимущества перед newsequentialid, в том числе тот факт, что они не являются черным ящиком, что вы можете использовать эту формулу вне ограничения по умолчанию и что вы можете использовать эту формулу вне SQL Server.
Спасибо, yfeldblum! Ваше простое и краткое объяснение GUID COMB действительно помогло мне. Я на самом деле смотрел на обратную сторону этого поста: мне пришлось уйти от надежды на newsequentialid()
так как я пытался перенести базу данных SQL Server 2012 в Azure, и newsequentialid()
функция там не поддерживается.
Я смог изменить все значения PK моей таблицы по умолчанию на GUID COMB со следующим синтаксисом:
ALTER TABLE [dbo].[Company]
ADD CONSTRAINT [DF__Company__Company_ID__72E6D332]
DEFAULT (CONVERT([uniqueidentifier],CONVERT([binary](10),newid(),0)+CONVERT([binary](6),getdate(),0),0)) FOR [CompanyId]
GO
Моя база данных SQL2012 счастливо живет в облаке Azure.
Если это SQL Server, вы генерируете Guid, вызывая newid(). Это не хорошо для первичных ключей. Используйте целочисленный столбец идентификаторов для первичного ключа и сделайте свой Guid суррогатным ключом (и столбцом guid строки).