Один и тот же запрос использует разные индексы? - PullRequest
5 голосов
/ 30 июня 2009

Может ли запрос на выбор использовать разные индексы, если изменяется значение условия where?

Два следующих запроса используют разные индексы, и единственное различие заключается в значении условие и typeenvoi = 'EXPORT' или и typeenvoi = 'MAIL'

select numenvoi,adrdest,nomdest,etat,nbessais,numappel,description,typeperiode,datedebut,datefin,codeetat,codecontrat,typeenvoi,dateentree,dateemission,typedoc,numdiffusion,nature,commentaire,criselcomp,crisite,criservice,chrono,codelangueetat,piecejointe, sujetmail, textemail
            from v_envoiautomate
            where etat=0 and typeenvoi='EXPORT'
            and nbessais<1 


select numenvoi,adrdest,nomdest,etat,nbessais,numappel,description,typeperiode,datedebut,datefin,codeetat,codecontrat,typeenvoi,dateentree,dateemission,typedoc,numdiffusion,nature,commentaire,criselcomp,crisite,criservice,chrono,codelangueetat,piecejointe, sujetmail, textemail
            from v_envoiautomate
            where etat=0 and typeenvoi='MAIL'
            and nbessais<1

Может кто-нибудь дать мне объяснение?

Ответы [ 3 ]

9 голосов
/ 30 июня 2009

Сведения об индексах хранятся как статистика в наборе данных гистограммного типа в SQL Server.

Каждый индекс разбивается на диапазоны, и каждый диапазон содержит сводку ключевых значений в этом диапазоне, например:

  • диапазон Высокое значение
  • количество значений в диапазоне
  • количество различных значений в диапазоне (количество элементов)
  • количество значений, равных верхнему значению

... и т. Д.

Вы можете просмотреть статистику по данному индексу с помощью:

DBCC SHOW_STATISTICS(<tablename>, <indexname>)

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

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

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

Статистика, на которой основаны эти суждения, также может сильно различаться; По умолчанию SQL Server производит выборку лишь небольшого процента строк любой существенной таблицы, поэтому селективность этого индекса может не отражать целое. Это особенно проблематично, если в индексе есть крайне неуникальные ключи.

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

4 голосов
/ 30 июня 2009

Оптимизатор запросов в SQL Server (как и в большинстве современных платформ СУБД) использует методологию, известную как «оптимизация на основе затрат». Для этого он использует статистику по таблицам в базе данных для оценки необходимого количества операций ввода-вывода. Оптимизатор рассмотрит несколько семантически эквивалентных планов запросов, которые он генерирует путем преобразования базового плана запросов, сгенерированного путем синтаксического анализа оператора.

Каждый план оценивается по стоимости с помощью эвристики на основе статистики, хранящейся в таблицах. Статистика представлена ​​в различных вариантах:

  • Количество строк таблицы и индекса

  • Распределение гистограмм значений в отдельных столбцах.

Если вхождение «MAIL» в сравнении с «EXPORT» на гистограммах распределения значительно отличается, оптимизатор запросов может предложить различные оптимальные планы. Это, вероятно, то, что случилось.

2 голосов
/ 30 июня 2009

Вероятно, имеет отношение к "кардинальности", я полагаю, слова значений в таблице. Если есть много строк, которые соответствуют этому предложению, SQL Server может решить, что один запрос будет более эффективным, используя индекс для другого столбца. Это крайний случай, но если бы была одна строка, которая соответствовала «MAIL», он, вероятно, использовал бы этот индекс. Если бы каждая вторая строка в таблице была «EXPORT», но только половина из этих «EXPORT» строк имела etat, равную 0, то она, вероятно, использовала бы индекс этого столбца.

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