Я после некоторого подтверждения этой идеи, чтобы исправить плохо работающую базу данных или лучшее предложение, если кто-то есть. Всегда открыт для лучших предложений.
У меня очень большая база данных (более 20 миллионов записей растет примерно на 1/2 миллиона в день), которые используют GUID в качестве PK.
С моей стороны это недосмотр, но ПК кластеризован на сервере SQL и вызывает проблемы с производительностью.
Причина для guid - эта база данных частично синхронизирована со 150 другими базами данных, поэтому PK должен быть уникальным. SQL Server не управляет синхронизацией, скорее, существует специальный процесс, который синхронизирует данные в соответствии с требованиями системы - все на основе этого GUID.
Каждая из 150 удаленных баз данных не хранит полные данные, хранящиеся в центральной базе данных SQL. они хранят только подмножество данных, которые им действительно необходимы, и данные, которые им требуются, не являются уникальными для них (например, 10 из 150 баз данных могут иметь одни и те же записи из баз данных других сайтов - они совместно используют). Кроме того, данные на самом деле генерируются на удаленных сайтах, а не в центральной точке, поэтому необходимы GUID.
Центральная база данных используется не только для синхронизации всего, но и к этой очень большой фрагментированной базе данных будут выполняться запросы от 3000+ пользователей. Уже это большая проблема при первоначальном тестировании.
К счастью, мы еще не живы - так что я могу вносить изменения и отключать их, если требуется, что является чем-то еще.
Производительность удаленных баз данных не является проблемой - подмножества данных довольно малы, а размер базы данных обычно не превышает 1 ГБ. Записи возвращаются в основную систему довольно регулярно и удаляются из меньших дисков BD, когда они больше не нужны.
Производительность центральной БД, которая хранит все записи, ужасна - из-за кластерного GUID в качестве первичного ключа для такого количества записей. Фрагментация индекса находится вне графика.
Итак, мои мысли по поводу исправления проблемы с производительностью - создать новый столбец BIGINT IDENTITY без знака (1,1), а затем изменить кластеризованный PK столбца BIGINT таблицы.
Я бы создал уникальный некластеризованный индекс в поле GUID, который был первичным ключом.
Меньшим удаленным базам данных 150 не нужно знать о новом ПК в базе данных Central SQL Server - он будет использоваться исключительно для организации данных в базе данных и предотвращения плохой производительности и фрагментации.
Будет ли это работать и улучшить производительность центральной базы данных SQL и предотвратить адскую фрагментацию в будущем (в определенной степени, конечно)? или я пропустил что-то очень важное здесь, которое подпрыгнет и укусит меня и вызовет еще больше горя?
источник
int
за 4255 дней (11,5 лет). Если бы он сделал это, он бы обвинял вас только в 11,5 лет;)Ответы:
Вам, конечно, не нужно кластеризоваться на GUID. Если у вас есть что-то, что позволит вам уникально идентифицировать записи, отличные от этого GUID, я бы посоветовал вам взглянуть на создание уникального индекса для этого другого поля и кластеризацию этого индекса. Если нет, вы можете кластеризовать другие поля, даже используя неуникальные индексы. Подход, заключающийся в кластеризации, однако, лучше всего облегчает разделение ваших данных и запросов - так что, если у вас есть поле «регион» или что-то еще, это может быть кандидатом для вашей схемы кластеризации.
Проблема с переходом на a
BIGINT
будет заключаться в добавлении данных из других баз данных и интеграции их базы данных в центральное хранилище. Если это не рассмотрение - и никогда не будет рассмотрение - тогда, да,BIGINT
это решило бы проблему перебалансировки индекса.За кулисами, если вы не укажете кластеризованный индекс, SQL Server делает то же самое: он создает поле идентификатора строки и отображает в нем все остальные индексы. Таким образом, делая это самостоятельно, вы решаете это так же, как это решает SQL.
источник
Это высокий заказ.
Позвольте мне предложить подход среднего человека.
У меня были проблемы с System.Guid.NewGuid (), генерирующей случайные направляющие. (Я позволял клиенту создавать свой собственный guid, вместо того чтобы полагаться на базу данных для создания sequentialid).
Как только я перешел на UuidCreateSequential на стороне клиента, моя производительность стала НАМНОГО лучше, особенно на INSERT.
Вот код клиента DotNet вуду. Я уверен, что я заложил откуда-то
АЛЬТЕРНАТИВНАЯ ИДЕЯ:
Если ваша основная база данных и удаленная база данных «связаны» (как, например, sp_linkserver) ...... тогда вы можете использовать основную базу данных в качестве «генератора uuid».
Вы не хотите, чтобы Uuid "один за другим", это слишком много болтливости.
Но вы можете взять набор UUID.
Ниже приведен код:
/ *
* /
источник
Исходя из вашего описания, идти с BIGINT. Однако индекс для GUID может быть неуникальным, поскольку предполагается, что GUID в любом случае должен быть глобально уникальным.
источник
Если GUID хранится правильно как uniqueidentifier, не должно быть проблем с производительностью ... и если вы можете использовать Sequential GUID еще лучше ...
Кроме того, @mattytommo имеет хороший момент около 11,5 лет с использованием INT ...
источник