Изменение в базе данных из-за использования GUID (уникального идентификатора)

#c# #sql-server #database-design #guid #uniqueidentifier

#c# #sql-сервер #база данных-дизайн #guid #уникальный идентификатор

Вопрос:

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

Короче говоря, время отклика в некоторых таблицах с 5 тысячами строк очень низкое. И эти таблицы будут увеличиваться в размере.

Некоторые из этих таблиц (например, таблица заголовка заказа) имеют uniqueidentifier в качестве P.K. Мы полагаем, что это может быть причиной низкого времени отклика.

Изучив ситуацию, мы решили использовать следующие варианты

  1. Преобразуйте индекс первичного ключа в заголовке порядка таблиц в некластеризованный.
  2. Используйте newsequentialid() в качестве значения по умолчанию для PK вместо newid()
  3. Преобразуйте PK в bigint

Мы считаем, что вариант № 2 идеален, поскольку вариант № 3 потребует больших изменений в билете.

Но для реализации этого нам нужно перенести часть нашей обработки в хранимых процедурах insert в триггеры. Это потому, что нам нужно перехватить PK из таблицы OrderHeader, и мы не можем использовать

Выберите @OrderID = newsequentialid() в хранимой процедуре insert.

Принимая во внимание, что если мы переместим обработку в триггер, мы можем использовать

выберите OrderID из вставленного

Теперь вопросы?

  1. Приведет ли преобразование PK из newid() в newsequentialid() к увеличению производительности?

  2. Решит ли преобразование индекса PK в некластеризованный и сохранение как uniqueidentifier в качестве типа данных для PK, так и newid() для генерации PK наши проблемы?

  3. Если вы столкнулись с подобной ситуацией, пожалуйста, позвольте дать полезный совет

Заранее огромное спасибо людям

Romi

Комментарии:

1. Как вы думаете, почему проблема в unqiue? Звучит странно для меня. Вы знаете, что при запросе witch база данных работает медленно? Вы запускали трассировку для анализа проблемы? Вы ознакомились с планом выполнения? Не могли бы вы опубликовать «проблемные» запросы, чтобы мы могли проанализировать, действительно ли проблема в PK?

Ответ №1:

Преобразуйте индекс первичного ключа в заголовке порядка таблиц в некластеризованный.

Кажется хорошим вариантом для выполнения независимо от того, что вы делаете. Если ваша таблица кластеризована с использованием вашего pkey, а последний является UUID, это означает, что вы постоянно пишете где-то в середине таблицы вместо добавления новых строк в ее конец. Это само по себе приведет к снижению производительности.

Предпочитайте кластеризовать свою таблицу, используя индекс, который действительно полезен для сортировки; в идеале что-то в поле даты, менее идеально (но все равно очень полезно) заголовок / name и т.д.

Комментарии:

1. Это я сделаю в любом случае. Но дело в том, что после того, как я преобразовываю индекс в некластеризованный, нужно ли мне использовать newsequentialid() вместо newid ()? Или достаточно просто изменить индекс на некластеризованный?

2. Использование newsequentialid() вместо newid() означает, что у вас будет меньше случайных uuid, но они все равно случайным образом приведут вас в середину таблицы. Ваша реальная проблема заключается в том, что из-за кластеризации на чем-то изначально случайном ваши строки находятся повсюду в таблице (что приводит к множеству случайных запросов на диск).

3. (Далее) Если у вас есть дата, которая слабо соответствует критериям заказа, а также порядку, в котором они вставлены, она будет гораздо более подходящей для кластеризации, например, billing_date (или issue_date) для таблицы заказов.

4. Денис, спасибо за полезный вклад. Я буду преобразовывать индекс PK в некластеризованный и создавать кластеризованный индекс для других соответствующих столбцов. Еще один момент заключается в том, что мне, возможно, придется объединить таблицу orders с другими таблицами, которые также используют uniqueidentifier в качестве PK. Итак, в долгосрочной перспективе будет ли мне лучше использовать newsequentialid() в качестве PK, а также преобразовать все существующие PK в newssequentialID()?

5. Повторите это, рассмотрите возможность использования int (или bigint, если у вас более 2 миллиардов строк) вместо pkey и сохраните uuid в качестве ссылки для синхронизации в распределенных средах. Эта проблема соединения заключается в том, что лично я никогда не использую uuid в качестве pkeys (но у меня почти всегда где-то есть uuid для синхронизации). И да, в этом случае последовательный uuid может иметь небольшое преимущество.

Ответ №2:

Переместите кластеризованный индекс из столбца GUID в какую-либо другую комбинацию столбцов (например, наиболее часто выполняемый поиск по диапазону)

Пожалуйста, опубликуйте структуру вашей таблицы и определения индексов, а также проблемные запросы

Прежде чем вносить какие-либо изменения: вам необходимо измерить и определить, где находится ваше фактическое узкое место.

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

Кроме того, актуальна ли ваша статистика? Вы регулярно перестраиваете индексы?

Комментарии:

1. Мы используем Select @OrderID = newid() в процедуре вставки.

2. @ Romi24 : этого недостаточно информации.