Будет ли использоваться мой индекс, если не будут использованы все столбцы?

StackOverflow https://stackoverflow.com/questions/135530

Вопрос

У меня есть индекс по столбцам A, B, C, D таблицы T.

У меня есть запрос, который извлекается из T с A, B, C в предложении WHERE.

Будет ли использоваться индекс или потребуется отдельный индекс, включающий только A, B, C?

Это было полезно?

Решение

Дэвид Б. прав: вам следует проверить план выполнения, чтобы убедиться, что индекс используется.

Будет ли использоваться индекс или потребуется отдельный индекс, включающий только A, B, C?

Чтобы ответить на эту последнюю часть вопроса, которая, как мне кажется, является основной темой (в отличие от немедленного решения), есть почти никогда не является причиной индексации подмножества проиндексированных столбцов.Если ваш индекс (A, B, C, D), WHERE против (A, B, C), скорее всего, приведет к индексу искать, что является идеальной ситуацией — индекс включает в себя всю информацию, необходимую механизму для перехода непосредственно к набору результатов.Я считаю, что это справедливо для числовых типов и для тестов на равенство в строковых типах, хотя это может быть нарушено с помощью LIKE '%').С другой стороны, если ваш WHERE ссылается только на D, вы, скорее всего, получите индекс сканировать, что будет означать, что механизму SQL придется сканировать все комбинации A, B и C, а затем проверять, соответствует ли D вашим критериям, прежде чем решить, добавлять ли строку в набор результатов.В особенно большой таблице, когда мне пришлось выполнять много запросов к столбцу «D», я добавил дополнительный индекс только для D и увидел улучшение производительности примерно на 90%.

Редактировать:Я также рекомендую использовать советник по настройке ядра СУБД в SQL Management Studio.Он сообщит вам, если ваша таблица не индексирована идеально для запроса, который вы хотите выполнить.

Другие советы

Это зависит!

WHERE A like '%x%'
  and B = 1
  and C = 1
//
WHERE A = 1
  OR B = 1
  OR C = 1
//
WHERE DateAdd(dd, 1, A) = '2008-01-01'
  AND B = 1
  AND C = 1

Они не будут полагаться на индекс, потому что индекс бесполезен.

Нажмите «Показать предполагаемый план выполнения», чтобы подтвердить потенциальное использование индекса.

в базах данных Oracle это называется Композитный индекс (документы 12g, но действительны для более ранних версий)

Составные индексы могут ускорить получение данных для операторов SELECT, в которых предложение WHERE ссылается на все начальные части столбцов составного индекса.Поэтому порядок столбцов, используемых в определении, важен.Обычно наиболее часто используемые столбцы идут первыми.

так что в вашем случае да.индекс можно/можно использовать.это можно проверить, используя план объяснения.

если MS SQLSERVER отличается (и я подозреваю, что это возможно), вам понадобится новый ответ.

Редактировать:Следует также упомянуть, что это будет только учитывать индекс для использования..это не обязательно означает, что он БУДЕТ его использовать.

Редактировать2:В Oracle 11g и более поздних версиях теперь есть опция, позволяющая пропускать столбцы в индексе.поэтому запрос к A, B и D может по-прежнему использовать индекс

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

Как и в случае с подобными вещами, не верьте мне на слово – сравните это.Создайте таблицу, заполните ее репрезентативными данными, запросите ее, проиндексируйте и снова запросите.

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

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

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

Начните с простого поиска равных (ГДЕ A=1, B='Red' и C=287), да, индекс (скорее всего) будет использоваться.Индекс будет использоваться сначала, чтобы помочь оптимизатору «угадать» количество строк, соответствующих выбранному, а затем, во-вторых, для фактического доступа к этим строкам.

В ответ на комментарий Дэвида Б. о предикате «like» SQLServer все равно может использовать индекс, это зависит от того, что вы выбираете.Например, если вы выбираете count(*), то SQLServer, скорее всего, будет сканировать индекс и подсчитывать попадания, соответствующие предложениюwhere, поскольку индекс меньше и для сканирования потребуется меньше операций ввода-вывода.И он может решить сделать это, даже если вы выбираете некоторые столбцы из базовой таблицы, в зависимости от того, насколько SQLServer считает индекс избирательным.

Вот еще один ответ «это зависит»...это также зависит от размера вашего стола...

Я согласен со всеми, кто упомянул проверку плана выполнения, чтобы проверить, используется ли ваш индекс.

Вот пара статей о чтении плана выполнения, которые могут оказаться вам полезными:

http://www.sqlservercentral.com/articles/Administering/executionplans/1345/ http://www.codeproject.com/KB/database/sql-tuning-tutorial-1.aspx

Также есть хорошая статья о Seeks vs.сканы, которые я бы порекомендовал:http://blogs.msdn.com/craigfr/archive/2006/06/26/647852.aspx

В блоге Крейга Фридмана есть множество хороших статей, вот еще одна, которая может оказаться вам полезной.В этой статье рассказывается о некоторых факторах, которые SQL Server использует для определения того, какой индекс использовать...

http://blogs.msdn.com/craigfr/archive/2006/07/13/664902.aspx

Заботиться!Джефф

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

Следовательно, вы можете воспользоваться этим при разработке индексов.Скажем, например, у меня есть таблица, которая содержит A, B, C в качестве ключевых значений и столбцы Y и Z, содержащие данные, которые, как я знаю, будут часто извлекаться с помощью операторов.

SELECT Y FROM table WHERE A = alpha and B = beta and C = gamma 

SELECT Z FROM table WHERE A = alpha and B = beta and C = gamma 

Обычно я создаю индекс для A, B, C, X, Z, предполагая, что X и Z — это достаточно маленькое поле.Причина этого в том, что я знаю, что путь доступа в приведенных выше утверждениях будет использовать индекс, и поскольку данные, которые я хочу получить, уже находятся в прочитанном индексе тогда не потребуется отдельного чтения блока данных, необходимого для получения самих данных таблицы.Эта стратегия может значительно ускорить получение данных в некоторых обстоятельствах.Конечно, вы платите за это затратами на обновление и дисковым пространством, поэтому вам необходимо понять, что делает ваша база данных, прежде чем применять ее, но, поскольку в большинстве баз данных количество операций чтения значительно превышает число операций записи, это, как правило, стоит внимания.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top