Использование некластеризованного индекса в столбце guid type в SQL Server

Я бы хотел оптимизировать производительность базы данных, которую моя команда использует для приложения.

Я искал области для добавления внешних ключей и, в свою очередь, индексировал эти столбцы, чтобы повысить производительность соединений. Однако многие из наших таблиц объединены в id, который является типом GUID, сгенерированным при вставке элемента, а данные, связанные с этим элементом в других таблицах, обычно содержат столбец item_id, содержащий GUID.

Я читал, что добавление кластеризованных индексов в столбцы типа GUID является очень плохим решением, потому что индекс должен быть постоянно реконструирован, чтобы быть эффективным. Однако мне было интересно, есть ли какой-либо ущерб использованию некластеризованного индекса в описанном выше сценарии? Или разумно предположить, что это поможет производительности? При необходимости я могу предоставить дополнительную информацию.

Ответ 1

Индекс на <anytype> на сегодняшний день является наилучшим вариантом для улучшения объединений и однократного поиска. Не имея этого индекса, запрос всегда должен будет сканировать всю таблицу из конца в конец с (часто) ужасающими результатами производительности и concurrency спуститься вниз.

Верно, что uniqueidentifier делает неправильный выбор для индексов по причинам, которые вы упомянули, но отнюдь не означает, что вы не должны создавать эти индексы. Если возможно, рекомендуется изменить тип данных на INT или BIGINT. Используя NEWSEQUENTIALID() или UuidCreateSequential, чтобы сгенерировать их помощь в вопросах фрагментации. Если все альтернативы не удастся, вам, возможно, придется чаще выполнять операции по индексированию (перестраивать, реорганизовывать), чем для других индексов. Но ни в коем случае ни один из этих недостатков не перевешивает выгоду от наличия индекса в первую очередь!

Ответ 2

Два исполнения:
- вставить
- выберите

Индекс должен улучшить выбор

Индекс замедляет замедление вставки.
Если вставки находятся в порядке, индекс не фрагментируется.
Если вставки не упорядочены, индекс будет фрагментировать.
Фрагментация индекса замедляет вставку и выбор.
Через обслуживание можно дефрагментировать индекс.

Добавление некластеризованного индекса в столбец, который ссылается на FK, поможет соединениям.
Поскольку этот столбец, скорее всего, не заказал этот факт, это GUID не потерял.

В самой таблице FK указывается, где GUID не является хорошим кандидатом для ПК (кластерный индекс).
С GUID как PK, который индексирует фрагменты на вставке.
Int или последовательный идентификатор являются лучшими кандидатами, поскольку они не будут фрагментировать PK для вставки.
Но не стоит просто дефрагментировать эти таблицы.

Ответ 3

Это обычно помогает производительности. Но вы можете создать индекс с заполняющим фактором менее 100%, так что неизбежные разрывы страниц не должны происходить довольно часто. Регулярное обслуживание индекса, безусловно, было бы плюсом.

Ответ 4

Да, вам лучше изменить индекс Guid с кластеризованного на некластеризованный. Руководство по-прежнему может быть первичным ключом, и вам не нужно изменять ваш запрос/исходный код. Нет переупорядочивания данных и повышения производительности.

В таких базах данных, как SQL Azure, обязательно иметь кластеризованный индекс. Таким образом, вы можете использовать поле date/datetime. Создание дополнительного столбца int-identity/autoincrement не требуется, поскольку некоторые разработчики в одной команде обычно используют те и другие GUID. Результатом является несогласованное применение. Так что держите только GUID.. полную остановку!

Говоря о последовательных гидах, я думаю, что гиды лучше созданы из кода, чем из базы данных. Современные DAL и шаблоны репозитория не предпочитают зависимости от DB для CRUD. например сценарий: запрос linq и автоматические сборки с модульным тестированием без зависимости от БД. И создание последовательного руководства - это не очень хорошая идея (по крайней мере для меня). Так что в качестве первичного ключа с некластеризованным индексом - лучший вариант.

У меня есть поддержка от Microsoft по некластеризованной теме http://blogs.msdn.com/b/sqlazure/archive/2010/05/05/10007304.aspx

Отредактировано: Backing is off ( "No Resource Found" )

Ответ 5

Да, некластеризованный индекс был бы идеальным для вашей ситуации. В основе лежит B-дерево, такое как кластерный индекс, но базовые данные в таблице не сортируются, поэтому проблем с непоследовательным характером GUID не существует. Индекс NC существует отдельно от таблицы.

Будьте осторожны, чтобы не добавлять слишком много некластеризованных индексов. Оптимизируйте только там, где вам нужно. Запустите профайлер, чтобы посмотреть, какие запросы занимают много времени, и оптимизируйте только те. Кроме того, не забудьте установить коэффициент заполнения на значение < 50%, если только база данных редко получает какие-либо обновления, или пространство является ограничением.

Соответствующий MSDN: http://msdn.microsoft.com/en-us/library/ms177484(v=sql.105).aspx