Поддерживает ли порядок столбцов в выражении WHERE?
например.
Скажем, я поставил столбец с более высоким потенциалом для уникальности сначала или наоборот?
Поддерживает ли порядок столбцов в выражении WHERE?
например.
Скажем, я поставил столбец с более высоким потенциалом для уникальности сначала или наоборот?
С хорошим оптимизатором запросов: он не должен.
Но на практике я подозреваю, что это возможно.
Вы можете рассказать только о своих случаях, измеряя. И измерения, скорее всего, будут меняться по мере изменения данных в базе данных.
Для Transact-SQL существует определенный приоритет для операторов в условии условия WHERE. Оптимизатор может переопределить эту оценку, поэтому вам не следует полагаться на поведение короткого замыкания для правильности. Порядок, как правило, слева направо, но выборочность/доступность индексов, вероятно, также имеет значение. Упрощение условия поиска должно улучшить способность оптимизатора к его обработке.
Пример:
WHERE (a OR b) AND (b OR c)
можно упростить до
WHERE b OR (a AND c)
Очевидно, что в этом случае, если запрос может быть сконструирован для того, чтобы определить, выполняется ли b сначала, он может пропустить оценку a и c и таким образом будет работать быстрее. Независимо от того, может ли оптимизатор выполнить это простое преобразование, я не могу ответить (он может это сделать), но дело в том, что он, вероятно, не может делать сколь угодно сложных преобразований, и вы можете повысить эффективность запросов, переставив свое условие. Если b более избирательно или имеет индекс, оптимизатор, скорее всего, сможет сначала построить запрос, используя его.
EDIT. Что касается вашего вопроса о заказе на основе уникальности, я бы предположил, что любые подсказки, которые вы можете предоставить оптимизатору на основе ваших знаний (фактических, а не предполагаемых) данных, могли бы "Больно. Представьте, что он не будет делать никакой оптимизации и не будет строить ваш запрос так, как если бы вам нужно было определить его от большей части до наименее избирательного, но не зацикливайтесь на нем, пока производительность не будет проблемой.
Цитата из приведенной выше справки:
Порядок приоритетности для логических операторов НЕ (самый высокий), затем следует AND, а затем OR. Скобки могут использоваться для переопределения это приоритет в условии поиска. Порядок оценки логические операторы могут варьироваться в зависимости от выбора, сделанного запросом оптимизатор.
Для SQL Server 2000/20005/2008 оптимизатор запросов обычно дает вам одинаковые результаты независимо от того, как вы упорядочиваете столбцы в предложении WHERE. Сказав это, за годы написания тысяч команд T-SQL я нашел несколько угловых случаев, когда заказ изменил производительность. Вот некоторые характеристики запросов, которые, как представляется, подвержены этой проблеме:
Если в вашем запросе имеется большое количество таблиц (10 или более).
Если у вас есть несколько EXISTS, IN, NOT EXISTS или NOT IN в предложении WHERE
Если вы используете вложенные CTE (выражения common-table) или большое количество CTE.
Если у вас есть большое количество подзапросов в предложении FROM.
Вот несколько советов по попытке оценить лучший способ быстро решить проблему производительности:
Если проблема связана с 1 или 2, попробуйте переупорядочить предложение WHERE и сравните стоимость поддерева запросов в оцененных планах запросов.
Если проблема связана с 3 или 4, попробуйте переместить подзапросы и CTE из запроса и заставить их загружать временные таблицы. Оптимизатор плана запроса более эффективен при оценке планов запросов, если вы уменьшите количество сложных объединений и подзапросов из тела оператора T-SQL.
Если вы используете временные таблицы, убедитесь, что вы указали первичные ключи для временных таблиц. Это означает, что вы не используете SELECT INTO FROM для создания таблицы. Вместо этого явно создайте таблицу и укажите основной ключ перед использованием инструкции INSERT INTO SELECT.
Если вы используете временные таблицы, а многие процессы на сервере также используют временные таблицы, то вы можете захотеть создать более постоянную промежуточную таблицу, которая будет усечена и перезагружена во время процесса запроса. Если вы используете TempDB для хранения рабочих/промежуточных таблиц, у вас больше шансов столкнуться с проблемами конкуренции с дисками.
Переместите операторы в предложении WHERE, которое будет фильтровать большинство данных в начале предложения WHERE. Обратите внимание, что если это ваше решение проблемы, вы, вероятно, будете иметь плохую производительность снова по линии, когда план запроса снова запутается в создании и выборе наилучшего плана выполнения. Вы НЕОБХОДИМО найти способ уменьшить сложность запроса, чтобы порядок предложения WHERE больше не был актуальным.
Надеюсь, вы найдете эту информацию полезной. Удачи!
Все зависит от СУБД, оптимизатора запросов и правил, но в целом это влияет на производительность.
Если предложение where упорядочено таким образом, что первое условие значительно уменьшает результат, остальные условия должны оцениваться только для меньшего набора. Следуя этой логике, вы можете оптимизировать запрос на основе порядка условий в предложении where.
В теории любые два запроса, которые эквивалентны, должны создавать идентичные планы запросов. Поскольку порядок предложений WHERE
не влияет на логический смысл запроса, это должно означать, что порядок предложения WHERE
не должен иметь эффекта.
Это связано с тем, как работает оптимизатор запросов. В значительно упрощенном обзоре:
JOIN
или SELECT
).Второй шаг - это абсолютно бессмысленный способ - он просто выбирает первое/наиболее очевидное физическое дерево, которое он может, однако на третьем этапе оптимизатор запросов способен просматривать все эквивалент физических планов (т.е. планов выполнения), и, пока запросы фактически эквивалентны, не имеет значения, какой первоначальный план мы получаем на шаге 2, набор планов, которые все планируют рассматривать на шаге 3, тот же.
(Я не могу вспомнить настоящие имена для логических/физических деревьев, они находятся в книге, но, к сожалению, эта книга сейчас является другой стороной мира)
Подробнее читайте в следующих статьях блога Внутри Оптимизатора: построение плана - часть 1
В действительности, однако часто оптимизатор запросов не имеет возможности рассматривать эквивалентные деревья all на шаге 3 (для сложных запросов может быть огромное количество возможных планы), и поэтому после некоторого времени отсечки шаг 3 сокращается, и оптимизатор запросов должен выбрать лучший план, который он нашел до сих пор - в этом случае не будут рассмотрены планы all.
Существует много за маской sceene, которая позволяет убедиться, что оптимизатор запросов выборочно и интеллектуально выбирает планы для рассмотрения, и поэтому большую часть времени план выбирает "достаточно хорошо" - даже если его не абсолютный самый быстрый план, вероятно, не намного медленнее, чем теоретически быстрый,
Однако это означает, что если у нас есть другой стартовый план на шаге 2 (что может произойти, если мы напишем наш запрос по-разному), это потенциально означает, что на третьем этапе рассматривается другой подмножество планов, и поэтому в теории SQL Server может придумать разные планы запросов для эквивалентных запросов в зависимости от того, как они были написаны.
В действительности, однако, в 99% случаев вы не заметите разницу (для многих простых планов там будет быть любая разница, поскольку оптимизатор действительно рассмотрит все планы). Также вы не можете предсказать, как все это будет работать, и поэтому вещи, которые могут показаться разумными (например, класть предложения WHERE
в определенном порядке), могут не иметь ничего похожего на ожидаемый эффект.
В подавляющем большинстве случаев оптимизатор запросов будет определять наиболее эффективный способ выбора запрошенных данных, независимо от порядка SARGS, определенного в предложении WHERE.
Порядок определяется такими факторами, как селективность рассматриваемого столбца (который SQL Server знает на основе статистики) и могут ли индексы использоваться.
Если вы являетесь условиями AND, первое не истинное значение вернет false, поэтому порядок может повлиять на производительность.