В теории любые два запроса, которые эквивалентны, должны давать идентичные планы запросов. Поскольку порядок предложений WHERE
не влияет на логическое значение запроса, это должно означать, что порядок предложений WHERE
не должен иметь никакого эффекта.
Это связано с тем, как работает оптимизатор запросов. В значительно упрощенном обзоре:
- Сначала SQL Server анализирует запрос и создает дерево логических операторов (например,
JOIN
или SELECT
).
- Затем он переводит эти логические операторы в «дерево физических операций» (например, «Вложенные циклы» или «Сканирование индекса», то есть план выполнения)
- Затем он переходит через набор эквивалентных «деревьев физических операций» (т. Е. Планов выполнения) путем замены эквивалентных операций, оценивая стоимость каждого плана до тех пор, пока не найдет оптимальный.
Второй шаг сделан совершенно незаметно - он просто выбирает первое / наиболее очевидное физическое дерево, которое может, однако на 3-м шаге оптимизатор запросов может просмотреть все эквивалентные физические данные. деревья (т. е. планы выполнения), и поэтому, если запросы фактически эквивалентны, не имеет значения, какой первоначальный план мы получим на шаге 2, набор планов, все планы для рассмотрения на шаге 3, одинаков.
(я не могу вспомнить настоящие имена для логических / физических деревьев, они есть в книге, но, к сожалению, книга - это другая сторона света от меня сейчас)
Подробнее об этом читайте в следующих статьях блога Внутри оптимизатора: построение плана - часть 1
В действительности однако часто оптимизатор запросов не имеет возможности рассмотреть все эквивалентных деревьев на шаге 3 (для сложных запросов может быть огромное количество возможных планов) и поэтому после определенного времени отсечения шаг 3 обрывается, и оптимизатор запросов должен выбрать лучший план, который он нашел на данный момент - в этом случае будут рассматриваться не все планов.
Существует много скрытого за этим волшебства, которое гарантирует, что оптимизатор запросов выборочно и осмысленно выбирает планы для рассмотрения, и поэтому большую часть времени план выбирает "достаточно хорошо" - даже если он не абсолютный самый быстрый план, вероятно, не намного медленнее, чем самый быстрый теоретический,
Однако это означает, что если у нас есть другой начальный план на шаге 2 (что может произойти, если мы напишем наш запрос по-другому), это потенциально означает, что на шаге 3 будет рассмотрено другое подмножество планов, и поэтому в теории SQL Server может предлагать разные планы запросов для эквивалентных запросов в зависимости от способа их написания.
В действительности, однако, в 99% случаев вы не заметите разницу (для многих простых планов не будет никакой разницы, так как оптимизатор фактически рассмотрит все планы). Кроме того, вы не можете предсказать, как все это будет работать, и поэтому вещи, которые могут показаться разумными (например, размещение предложений WHERE
в определенном порядке), могут не иметь ничего похожего на ожидаемый эффект.