Учитывая этот вопрос на Reddit, я очистил запрос, чтобы указать, где проблема была в запросе. Сначала я использую запятую, WHERE 1=1
чтобы упростить изменение запросов, поэтому мои запросы обычно заканчиваются так:
SELECT
C.CompanyName
,O.ShippedDate
,OD.UnitPrice
,P.ProductName
FROM
Customers as C
INNER JOIN Orders as O ON C.CustomerID = O.CustomerID
INNER JOIN [Order Details] as OD ON O.OrderID = OD.OrderID
INNER JOIN Products as P ON P.ProductID = OD.ProductID
Where 1=1
-- AND O.ShippedDate Between '4/1/2008' And '4/30/2008'
And P.productname = 'TOFU'
Order By C.CompanyName
Кто-то в основном сказал, что 1 = 1, как правило, ленив и плох для производительности .
Учитывая, что я не хочу «преждевременно оптимизировать» - я хочу следовать хорошей практике. Я смотрел на планы запросов раньше, но в основном только для того, чтобы узнать, какие индексы я могу добавить (или настроить), чтобы мои запросы выполнялись быстрее.
Тогда вопрос действительно ... Where 1=1
вызывает ли плохие вещи? И если так, как я могу сказать?
Незначительное редактирование: я всегда «предполагал», что 1=1
это будет оптимизировано или, в худшем случае, будет незначительным. Никогда не больно подвергать сомнению мантры, такие как «Goto's are Evil» или «Преждевременная оптимизация ...» или другие предполагаемые факты. Не был уверен 1=1 AND
, реально ли это повлияет на планы запросов или нет. Как насчет подзапросов? КТР - х? Процедуры?
Я не тот, кто оптимизирует, если в этом нет необходимости ... но если я делаю что-то действительно "плохое", я бы хотел свести к минимуму последствия или изменить их, где это применимо.
источник
Ответы:
SQL Server
синтаксический анализаторВ оптимизаторе есть функция «Constant Folding», которая исключает тавтологические выражения из запроса.Если вы посмотрите на план выполнения, нигде в предикатах вы не увидите этого выражения. Это подразумевает, что постоянное свертывание выполняется в любом случае во время компиляции по этой и другим причинам и не влияет на производительность запроса.
См. Сгибание констант и оценку выражений во время оценки мощности для получения дополнительной информации.
источник
Добавление избыточного предиката может изменить ситуацию в SQL Server.
В приведенных ниже планах выполнения обратите внимание на
@1
первый план по сравнению с литералом'foo'
во втором плане.Это указывает на то, что SQL Server рассматривал первый запрос для простой параметризации, чтобы способствовать повторному использованию плана выполнения - однако сравнение двух констант предотвращает это во втором случае.
Список условий, которые препятствуют простой параметризации (ранее известной как автоматическая параметризация), можно найти в Приложении A к Плану Кэширования Технических Документов Microsoft:
хотя простая параметризация обычно не является чем-то, на что вы должны полагаться. Гораздо лучше явно параметризовать ваши запросы.
источник
В любой современной СУБД (включая Oracle, Microsoft SQL Server и PostgreSQL - я в этом уверен) это не повлияет на производительность.
Как кто-то заметил, это повлияет только на фазу планирования запросов. Следовательно, разница будет видна только тогда, когда вы выполните тысячи итераций упрощенного запроса, который не возвращает никаких данных, таких как этот:
Для меня в PostgreSQL 9.0 это видно только с 10000 итерациями:
источник
Это может быть «проблемой» для Oracle, когда вы используете параметр базы данных cursor_sharing. Когда для этого параметра установлено значение «force», будут изменены все операторы SQL. Все «константы» в запросах будут заменены переменными связывания (например, 1 =>: SYS_0).
Эта опция была введена для работы с некоторыми ленивыми разработчиками. С другой стороны, это может также навредить другим ленивым разработчикам. Но риск не слишком высок. Начиная с 11g он имеет функцию просмотра переменных привязки.
источник