2013-05-14 4 views
6

У меня есть таблица с столбцами a, b, c, d, e, f, g, которая имеет примерно 500 000 строк.Является ли кластеризованный индекс быстрее, чем некластеризованный индекс с включенным?

Существует запрос, который запускается очень часто, что делает SELECT * FROM table WHERE a = @a AND b = @b AND c = @c.

ли лучше создать clustered index на а, Ь и с, ИЛИ я лучше от создания non-clustered index на а, Ь и с INCLUDE (d, e, f, g).

Не уверен, что включение поможет ускорить запрос с момента выбора select *.

Любая помощь будет оценена!

+1

Почему бы вам не сделать профилирование для обоих фактических данных? –

ответ

11

кластерный индекс будет вполне быстрый для этого SELECT, но это не обязательно может быть правильно выбор.

Кластерный индекс определяет порядок хранения записей физически (поэтому их можно использовать только для каждой таблицы). Таким образом, хотя это был бы самый быстрый запрос THAT, он может замедлить другие запросы и может KILL обновлять и вставлять, если один из этих столбцов меняется, что может означать, что запись должна быть физически переделана.

INCLUDE снова ускорит этот запрос за счет дополнительного хранения и дополнительного обслуживания индекса, если бы было обновлено любое из этих полей (включая включенные поля).

Я бы НАЧИНАл с некластеризованным индексом на a, b и c и посмотрел, достигает ли это вашей производительности разумного уровня. Что-нибудь еще может быть просто торгующей скоростью в одной области для медлительности в другой.

+0

Хороший вопрос. Отличный ответ. –

-3

Ваш кластеризованный индекс - это порядок хранения данных в таблице, поэтому вы можете иметь только один кластеризованный индекс для каждой таблицы. Если вы создаете новый индекс (не кластерный по умолчанию), убедитесь, что столбцы определены в индексе в том же порядке, что и они используются в предложении WHERE, что позволит SQL выполнить прямую индексацию, чтобы найти записи, ищу.

+5

Итак, какой вариант лучше? (так как это то, что задают) – Lamak

+1

Кластерный лучше, однако вы хотите, чтобы ваш кластеризованный индекс был уникальным (это слово?) индексом в таблице и несколькими столбцами, содержащимися в кластере, вам нужно подумать о том, как часто вы он будет вставляться в таблицу. Если вы вставляете данные, которые будут находиться между значениями, уже содержащимися в таблицах, вы будете вызывать много разбиений на страницы и фрагментацию индекса. В идеале значения (ы), используемые в вашем индексе с ограничениями, также не должны меняться. – MBulava

1

Кластеризованный индекс будет быстрее.

С SELECT * как ваши кластерные, так и некластерные (с включенными всеми) содержат все столбцы на каждой странице. Тем не менее, некластеризованный индекс ALSO содержит ссылку обратно на кластеризованный ключ - это требуется, если вы добавляете больше столбцов в таблицу, но на самом деле также потому, что все индексы (за исключением индексированных представлений) являются указателями на страницы данных. NCI не будет включать новые столбцы (фиксированные включают в себя список), но страницы данных будут.

SQL Server может быть достаточно умен, чтобы узнать, что SELECT * может быть выполнен с помощью INDEX SCAN на NCI (+ включает в себя) без закладки поиска вернуться к страницам данных, но даже тогда, что сканирование индекса будет один столбец шире, чем эквивалентное сканирование с кластерным индексом.

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

+0

Спасибо @ RichardTheKiwi, это очень помогает, не был на 100% уверен, как он работал под капотом. –

1

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

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

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

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

+0

Спасибо @ Cade, хорошие моменты. К сожалению, у меня нет никакой гибкости в запросе, это старый ORM, который в основном делает select * для любой таблицы, которую он связывает с внутренними объектами. Я пойду с некластеризованным. –

+0

@MarkKadlec Вам нужно будет следить за просмотром профилировщика или планов запросов в кеше, поскольку маловероятно, что некластеризованный индекс будет даже выбран (в зависимости от существующего кластерного индекса), и в этом случае некластеризованный индекс будет полной потерей пространства и времени обработки (поскольку каждое изменение в любых столбцах в любой строке также потребует обновления NCI, так как у вас есть все столбцы в любом ключе или столбцах без ключа). –

Смежные вопросы