У меня есть индекс для столбцов A, B, C, D таблицы T
У меня есть запрос, который тянет из T с A, B, C в предложении WHERE.
Будет ли использоваться индекс или будет нужен отдельный индекс, который включает только A, B, C?
У меня есть индекс для столбцов A, B, C, D таблицы T
У меня есть запрос, который тянет из T с A, B, C в предложении WHERE.
Будет ли использоваться индекс или будет нужен отдельный индекс, который включает только A, B, C?
Дэвид Б прав, что вы должны проверить план выполнения, чтобы убедиться, что индекс используется.
Будет ли использоваться индекс или будет нужен отдельный индекс, который включает только A, B, C?
Чтобы ответить на эту последнюю часть вопроса, которая, по моему мнению, является основной основной темой (в отличие от немедленного решения), почти нет причины индексировать подмножество индексированных столбцов. Если ваш индекс (A, B, C, D), то WHERE против (A, B, C), скорее всего, приведет к индексу seek, что является идеальной ситуацией - индекс включает всю информацию, которую движок должен перейти непосредственно к набору результатов. Я считаю, что это верно для числовых типов и для тестов равенства в строковых типах, хотя оно может разрушаться с помощью LIKE '%'). С другой стороны, если ваш WHERE ссылается только на D, вы, скорее всего, окажетесь с индексом scan, что означало бы, что 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 это называется Composite Index (12g docs, но действителен для более ранних версий)
Композитные индексы могут ускорять извлечение данных для операторов SELECT, в которых предложение WHERE ссылается на всю ведущую часть столбцов в составном индексе. Поэтому порядок столбцов, используемых в определении, важен. В общем, наиболее часто используемые столбцы идут в первую очередь.
поэтому в вашем случае, да. индекс мог бы/использоваться. это можно проверить, используя план объяснения.
если MS SQLSERVER отличается (и я подозреваю, что может), вам понадобится новый ответ.
Edit: Следует также упомянуть, что только рассмотрит индекс для использования.. это не обязательно означает, что он его использует.
Edit2: Теперь у Oracle 11g и более поздних версий есть опция, позволяющая пропускать столбцы в индексе. поэтому запрос на A, B и D может по-прежнему использовать индекс
Индекс будет использоваться, да. Это довольно разумно, какие индексы будут создавать более оптимальный план запроса, и с этим не должно быть никаких проблем.
Как и в случае с подобными вещами, не верьте мне на слово - сравнивайте это. Создайте таблицу, заполните ее репрезентативными данными, запросите ее, проиндексируйте и повторите запрос.
Тот факт, что индекс содержит столбец, который не используется в вашем запросе, не будет препятствовать его использованию.
Чтобы не сказать, что это определенно будет, его можно игнорировать по другой причине (возможно, потому, что один или несколько других индексов более полезны).
Как всегда, возьмите squizz в оценочном плане выполнения, чтобы увидеть, что может произойти.
Начните с простого поиска по равному (WHERE A = 1 и B = 'Red' и C = 287). Да, индекс будет (скорее всего) использоваться. Сначала индекс будет использоваться, чтобы помочь оптимизатору "угадать" количество строк, которые будут соответствовать выбранному, а затем второе, чтобы фактически получить доступ к этим строкам.
В ответ на комментарий Дэвида Б. о предикате "как" SQLServer все еще может использовать индекс, это зависит от того, что вы выбираете. Например, если вы выбираете счетчик (*), то SQLServer, скорее всего, сканирует индекс и подсчитывает числа, совпадающие с предложением where, поскольку индекс меньше, и для сканирования требуется меньшее количество IO. И он может решить сделать это, даже если вы выберете некоторые столбцы из базовой таблицы, в зависимости от того, насколько чувствителен SQL Server к индексу.
В общем, да, это будет, все современные базы данных достаточно умны, чтобы это сделать. Существуют исключения, например, если статистика в таблице показывает, что объем данных в нем достаточно мал, что полное чтение таблицы будет более эффективным, тогда индекс будет дисконтирован, но, как правило, вы можете положиться на него, когда это необходимо.
Следовательно, вы можете воспользоваться этим при разработке своих индексов. Скажем, например, у меня есть таблица, которая содержит A, B, C как ключевые значения, а числа Y и Z, содержащие данные, которые, как я знаю, будут часто извлекаться операторами
SELECT Y FROM table WHERE A = alpha и B = beta и C = gamma
SELECT Z FROM table WHERE A = alpha и B = beta и C = gamma
Я, как правило, создаю индекс на A, B, C, X, Z - считая, что X и Z - некоторое достаточно малое поле. Причина этого заключается в том, что я знаю, что путь доступа в приведенных выше выражениях будет использовать использование индекса, а поскольку данные, которые я хочу получить, уже находятся в считываемом индексе, тогда отдельное чтение блока данных, требуемого для извлечения данных таблицы сам будет необходим. Эта стратегия может значительно ускорить извлечение данных в некоторых случаях. Конечно, вы платите за это в расходах на обновление и на дисковое пространство, поэтому вам нужно понять, что делает ваша база данных, прежде чем применять его, но, как и в большинстве баз данных, чтение значительно превосходит количество записей, в целом это заслуживает внимания.
Здесь другой ответ "зависит"... он также зависит от того, насколько велика ваша таблица...
Я согласен со всеми, кто упомянул о проверке плана выполнения, чтобы проверить, используется ли ваш индекс.
Вот несколько статей по чтению плана выполнения, который вы должны найти полезным:
http://www.sqlservercentral.com/articles/Administering/executionplans/1345/ http://www.codeproject.com/KB/database/sql-tuning-tutorial-1.aspx
Там также хорошая статья о проверках против сканирования, которые я бы рекомендовал: http://blogs.msdn.com/craigfr/archive/2006/06/26/647852.aspx
В блоге Craig Freedman есть журнал хороших статей, здесь вы найдете полезный. В этой статье описываются некоторые факторы, которые SQL Server использует для определения того, какой индекс использовать...
http://blogs.msdn.com/craigfr/archive/2006/07/13/664902.aspx
Позаботьтесь! Джефф