Использование некластеризованного индекса для столбца типа guid в SQL Server
Я хотел бы оптимизировать производительность базы данных, которую моя команда использует для приложения.
Я искал области для добавления внешних ключей и, в свою очередь, индексировал эти столбцы для повышения производительности соединений. Однако многие из наших таблиц объединяются по идентификатору, который является GUID
тип, генерируемый при вставке элемента, и данные, связанные с этим элементом в других таблицах, обычно имеют столбец item_id
содержащий идентификатор GUID.
Я читал, что добавление кластеризованных индексов в столбцы типа GUID является очень плохим решением, поскольку индекс необходимо будет постоянно реконструировать, чтобы быть эффективным. Однако мне было интересно, есть ли какой-либо ущерб от использования некластеризованного индекса в описанном выше сценарии? Или разумно предположить, что это поможет производительности? Я могу предоставить больше информации, если это необходимо.
5 ответов
индекс <anytype>
Это, безусловно, лучший вариант, который вы должны улучшить соединения и одноэлементные поиски. В отсутствие этого индекса запрос всегда должен будет сканировать всю таблицу от конца до конца с (часто) ужасными результатами производительности и параллелизмом.
Это правда, что uniqueidentifier
делает плохой выбор для индексов по причинам, которые вы упомянули, но никоим образом не означает, что вы должны не создать эти индексы. Изменение типа данных на INT или БИГИНТ был бы весьма кстати, если бы это было возможно. Используя NEWSEQUENTIALID()
или UuidCreateSequential
для их создания поможет с проблемами фрагментации. Если все альтернативы терпят неудачу, вам может потребоваться выполнять операции обслуживания индекса (перестроения, реорганизации) чаще, чем для других индексов. но ни в коем случае ни один из этих недостатков не перевешивает преимущество наличия индекса в первую очередь!
два спектакля:
- вставить
- выберите
индекс должен улучшить select
индекс замедлит замедление вставки.
Если вставки расположены в порядке, индекс не фрагментируется.
Если вставки не в порядке, индекс будет фрагментировать.
Фрагментация индекса замедляет как insert, так и select.
Через обслуживание смогите дефрагментировать индекс.
добавление некластеризованного индекса в столбец, ссылающийся на FK поможет объединениям.
Поскольку этот столбец, скорее всего, не упорядочен, тот факт, что это GUID, не имеет потерь.
в самой таблице FK GUID не является хорошим кандидатом для PK (кластеризованный индекс).
С GUID как PK, который индексирует фрагменты на insert.
Int или sequential ID-лучшие кандидаты, поскольку они не будут фрагментировать ПК при вставке.
Но ничего страшного, просто дефрагментируйте эти столы.
обычно это помогает производительности. Но вы можете создать индекс с fillfactor менее 100%, так что неизбежные разбиения страниц не должны происходить так часто. Регулярное обслуживание индекса, безусловно, было бы плюсом.
да, вам лучше изменить индекс Guid с кластеризованного на некластеризованный. Guid все еще может быть первичным ключом, и вам не нужно изменять свой запрос/исходный код. Отсутствие переупорядочивания данных и повышение производительности.
в базах данных, таких как SQL Azure, обязательно иметь кластеризованный индекс. Таким образом, вы можете использовать поле date/datetime. Создание дополнительного столбца int-identity/autoincrement не требуется, поскольку некоторые разработчики в одной команде обычно используют эти и другие GUID. Получающийся в непоследовательном приложении. Поэтому держите только GUID.. полная остановка!
говоря о последовательных GUID, я думаю, что GUID лучше создаются из кода, чем из базы данных. Современные DALs и шаблоны репозиториев не предпочитают зависимости от БД для CRUD. например, сценарий: запрос linq и автоматизированные сборки с модульным тестированием без зависимости от БД. И создание последовательного guid сами по себе не является хорошей идеей(по крайней мере для меня). Таким образом, Guid как первичный ключ с некластеризованным индексом является лучшим вариантом.
У меня есть поддержка от Microsoft по некластеризованной теме http://blogs.msdn.com/b/sqlazure/archive/2010/05/05/10007304.aspx
отредактировано: Backing is gone ("ресурс не найден")
да, некластеризованный индекс идеально подходит для вашей ситуации. Базовым является B-дерево, как и кластеризованный индекс, но базовые данные в таблице не сортируются, поэтому проблем с непоследовательным характером GUID не существует. Индекс NC существует отдельно от таблицы.
будьте осторожны,чтобы не добавлять слишком много некластеризованных индексов. Оптимизируйте только там, где вам нужно. Запустить профайлер, чтобы увидеть, какие запросы занимают много времени, и оптимизировать только их. Кроме того, обязательно установите коэффициент заполнения в значение
соответствующий MSDN:http://msdn.microsoft.com/en-us/library/ms177484 (v=sql.105).aspx