Почему создание этого нового индекса так улучшило производительность, когда существующий индекс включил все столбцы в новый индекс? - PullRequest
5 голосов
/ 19 декабря 2011

У меня есть таблицы Log и LogItem;Я пишу запрос, чтобы получить некоторые данные из обоих.Существуют тысячи Logs, и у каждого Log может быть до 125 LogItems

Вопрос сложный, поэтому я его пропускаю (если кто-то считает, что это важно, я, вероятно, могу опубликовать его), но когда я запустил план оценочных запросов SSMS, он сказал мне, что новый некластеризованный индекс повысит производительность до 100%.

Existing Index: Non-clustered
Key Colums (LogItem): ParentLogID, DateModified, Name, DatabaseModified

Query Plan Recommendation
CREATE NONCLUSTERED INDEX [LogReportIndex]
ON [dbo].[LogItem] ([ParentLogID],[DatabaseModified])

Ради интереса я создал этот новый индекс и выполнил запрос иК моему большому удивлению, теперь мой запрос выполняется ~ 1 секунда, тогда как раньше было 10+ секунд.

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

примечание: я не думаю, что это потому, что SQL Server кэширует мои результаты, я выполнил запроспримерно 25-30 раз до того, как я создал индекс, и он постоянно занимал 10-15 секунд, после индекса он теперь постоянно равен ~ 1 или меньше.

Ответы [ 2 ]

6 голосов
/ 19 декабря 2011

Порядок столбцов в индексе важен.Если для фильтрации требуются столбцы 1 и 4 из индекса, индекс не поможет.Это полезно только при фильтрации по первым N последовательным столбцам.

Это потому, что индекс - это дерево.Вы не можете эффективно выбрать все узлы дерева, где column3 = something, потому что они разбросаны по всему остальному месту, принадлежащему различным значениям column1 и column2.Но если вы также знаете column1 и column2, то найти правую ветвь на дереве не составит труда.

2 голосов
/ 19 декабря 2011

Важным является передний край индекса.

Пока ваш запрос "покрыт" передним краем индекса, он будет эффективен.Индексы базы данных обычно реализуются как B-деревья, а структура B-дерева диктует, что поиск должен быть выполнен в определенном порядке, поэтому порядок полей в составном индексе имеет значение.

Если выиметь «дыры», например, если вы выполняете поиск по ParentLogID и DatabaseModified, но имеете индекс только по {ParentLogID, DateModified, Name, DatabaseModified}, тогда только часть индекса {ParentLogID} может быть эффективно использована.

(ПРИМЕЧАНИЕ. Некоторые СУБД могут использовать часть {DatabaseModified} через «сканирование с пропуском», но даже если ваша СУБД делает это, она гораздо менее эффективна, чем обычный индексный доступ) .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...