Имеет ли значение порядок столбцов в предложении WHERE? - PullRequest
33 голосов
/ 13 марта 2009

Порядок столбцов в предложении WHERE влияет на производительность?

, например

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

Ответы [ 7 ]

15 голосов
/ 13 марта 2009

С приличным оптимизатором запросов: не должно.

Но на практике я подозреваю, что это возможно.

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

12 голосов
/ 13 марта 2009

Для Transact-SQL существует определенный приоритет для операторов в условии предложения WHERE. Оптимизатор может переупорядочить эту оценку, поэтому вам не следует полагаться на короткое замыкание для корректности. Порядок, как правило, слева направо, но избирательность / доступность индексов, вероятно, также имеет значение. Упрощение условий поиска должно улучшить способность оптимизатора справиться с ним.

Ex:

 WHERE (a OR b) AND (b OR c)

может быть упрощено до

 WHERE b OR (a AND c)

Ясно, что в этом случае, если запрос может быть построен для определения, является ли b первым, он может пропустить оценку a и c и, таким образом, будет выполняться быстрее. Могу ли оптимизатор выполнить это простое преобразование, я не могу ответить (возможно, смогу), но дело в том, что он, вероятно, не может выполнять произвольно сложные преобразования, и вы сможете повлиять на производительность запроса, изменив условия. Если b более избирателен или имеет индекс, оптимизатор, вероятно, сможет сначала создать запрос, используя его.

РЕДАКТИРОВАТЬ : Что касается вашего вопроса об упорядочении на основе уникальности, я бы предположил, что любые подсказки, которые вы можете дать оптимизатору на основе вашего знания (фактического, не предполагаемого) данных, не могли больно Сделайте вид, что он не будет выполнять какую-либо оптимизацию, и построите ваш запрос так, как если бы вам нужно было определить его от наиболее до наименее избирательного, но не зацикливайтесь на этом, пока производительность не станет проблемой.

Цитата из ссылки выше:

Порядок приоритета для логических операторов НЕ (самый высокий), сопровождаемый И, сопровождаемый ИЛИ. Круглые скобки могут быть использованы для переопределения этот приоритет в условии поиска. Порядок оценки логические операторы могут варьироваться в зависимости от выбора, сделанного запросом оптимизатор.

8 голосов
/ 13 марта 2009

Для SQL Server 2000/20005/2008 оптимизатор запросов обычно дает одинаковые результаты независимо от того, как вы расположите столбцы в предложении WHERE. Сказав это, за годы написания тысяч команд T-SQL я обнаружил несколько угловых случаев, когда порядок изменял производительность. Вот некоторые характеристики запросов, которые оказались подвержены этой проблеме:

  1. Если в вашем запросе большое количество таблиц (10 или более).

  2. Если у вас есть несколько операторов EXISTS, IN, NOT EXISTS или NOT IN в предложении WHERE

  3. Если вы используете вложенные CTE (выражения общей таблицы) или большое количество CTE.

  4. Если в предложении FROM имеется большое количество подзапросов.

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

  1. Если проблема связана с 1 или 2, попробуйте изменить порядок предложения WHERE и сравните стоимость вложенного дерева запросов в оценочных планах запросов.

  2. Если проблема связана с 3 или 4, попробуйте переместить подзапросы и CTE из запроса и попросить их загрузить временные таблицы. Оптимизатор плана запросов более эффективен при оценке планов запросов, если вы сократите число сложных объединений и подзапросов из тела оператора T-SQL.

  3. Если вы используете временные таблицы, убедитесь, что вы указали первичные ключи для временных таблиц. Это означает, что следует избегать использования SELECT INTO FROM для генерации таблицы. Вместо этого явно создайте таблицу и укажите первичный ключ перед использованием оператора INSERT INTO SELECT.

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

  5. Переместите операторы в предложении WHERE, которые отфильтровывают большинство данных, в начало предложения WHERE. Обратите внимание, что если это ваше решение проблемы, то, вероятно, вы снова будете иметь низкую производительность, когда план запроса снова запутается с созданием и выбором наилучшего плана выполнения. Вы САМЫЙ ЛУЧШИЙ нашли способ уменьшить сложность запроса, чтобы порядок предложения WHERE больше не действовал.

Надеюсь, вы найдете эту информацию полезной. Удачи!

2 голосов
/ 11 апреля 2011

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

Это связано с тем, как работает оптимизатор запросов. В значительно упрощенном обзоре:

  1. Сначала SQL Server анализирует запрос и создает дерево логических операторов (например, JOIN или SELECT).
  2. Затем он переводит эти логические операторы в «дерево физических операций» (например, «Вложенные циклы» или «Сканирование индекса», то есть план выполнения)
  3. Затем он переходит через набор эквивалентных «деревьев физических операций» (т. Е. Планов выполнения) путем замены эквивалентных операций, оценивая стоимость каждого плана до тех пор, пока не найдет оптимальный.

Второй шаг сделан совершенно незаметно - он просто выбирает первое / наиболее очевидное физическое дерево, которое может, однако на 3-м шаге оптимизатор запросов может просмотреть все эквивалентные физические данные. деревья (т. е. планы выполнения), и поэтому, если запросы фактически эквивалентны, не имеет значения, какой первоначальный план мы получим на шаге 2, набор планов, все планы для рассмотрения на шаге 3, одинаков.

(я не могу вспомнить настоящие имена для логических / физических деревьев, они есть в книге, но, к сожалению, книга - это другая сторона света от меня сейчас)

Подробнее об этом читайте в следующих статьях блога Внутри оптимизатора: построение плана - часть 1

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

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

Однако это означает, что если у нас есть другой начальный план на шаге 2 (что может произойти, если мы напишем наш запрос по-другому), это потенциально означает, что на шаге 3 будет рассмотрено другое подмножество планов, и поэтому в теории SQL Server может предлагать разные планы запросов для эквивалентных запросов в зависимости от способа их написания.

В действительности, однако, в 99% случаев вы не заметите разницу (для многих простых планов не будет никакой разницы, так как оптимизатор фактически рассмотрит все планы). Кроме того, вы не можете предсказать, как все это будет работать, и поэтому вещи, которые могут показаться разумными (например, размещение предложений WHERE в определенном порядке), могут не иметь ничего похожего на ожидаемый эффект.

2 голосов
/ 13 марта 2009

Все зависит от СУБД, оптимизатора запросов и правил, но в целом это влияет на производительность.

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

0 голосов
/ 13 марта 2009

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

Порядок определяется такими факторами, как избирательность рассматриваемого столбца (который SQL Server знает по статистике) и возможность использования индексов.

0 голосов
/ 13 марта 2009

Если вы выполняете условия AND, первое неверное значение вернет false, поэтому порядок может повлиять на производительность.

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