Dada esta pergunta no reddit, limpei a consulta para apontar onde estava o problema na consulta. Eu uso vírgula primeiro e WHERE 1=1
para facilitar a modificação de consultas, então minhas consultas geralmente terminam assim:
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
Alguém basicamente disse que 1=1 geralmente é preguiçoso e ruim para o desempenho .
Dado que não quero "otimizar prematuramente" - quero seguir boas práticas. Já examinei os planos de consulta antes, mas geralmente apenas para descobrir quais índices posso adicionar (ou ajustar) para tornar minhas consultas mais rápidas.
A questão então realmente... faz Where 1=1
com que coisas ruins aconteçam? E se sim, como posso saber?
Edição secundária: Eu sempre 'assumi' também que isso 1=1
seria otimizado ou, na pior das hipóteses, seria insignificante. Nunca é demais questionar um mantra, como "Goto's are Evil" ou "Premature Optimization..." ou outros fatos presumidos. Não tinha certeza se 1=1 AND
afetaria realisticamente os planos de consulta ou não. E nas subconsultas? CTE's? Procedimentos?
Não sou de otimizar, a menos que seja necessário ... mas se estiver fazendo algo realmente "ruim", gostaria de minimizar os efeitos ou alterar quando aplicável.
O servidor SQL
analisadorO otimizador possui um recurso chamado "Constant Folding" que elimina expressões tautológicas da consulta.Se você observar o plano de execução, em nenhum lugar dos predicados verá essa expressão aparecer. Isso implica que a dobra constante é executada de qualquer maneira no tempo de compilação por esse e outros motivos e não tem efeito no desempenho da consulta.
Consulte Dobra constante e avaliação de expressão durante a estimativa de cardinalidade para obter mais informações.
A adição do predicado redundante pode fazer diferença no SQL Server.
Nos planos de execução abaixo, observe o
@1
no primeiro plano versus o literal'foo'
no segundo plano.Isso indica que o SQL Server considerou a primeira consulta de parametrização simples para promover a reutilização do plano de execução - porém a comparação de duas constantes impede que isso aconteça no segundo caso.
Uma lista de condições que impedem a parametrização simples (anteriormente conhecida como autoparametrização) pode ser encontrada no Apêndice A dos Documentos técnicos da Plan Caching Microsoft:
a parametrização simples geralmente não é algo em que você deva confiar. É muito melhor parametrizar explicitamente suas consultas.
Em qualquer RDBMS moderno (incluindo Oracle, Microsoft SQL Server e PostgreSQL - tenho certeza disso), isso não afetará o desempenho.
Como alguém observou, isso afetará apenas a fase de planejamento da consulta. Portanto, a diferença será visível apenas quando você executar milhares de iterações de uma consulta simplista que não retorna nenhum dado, como este:
Para mim, no PostgreSQL 9.0, isso é visível com apenas 10.000 iterações:
Isso pode ser um "problema" para o Oracle quando você usa o parâmetro de banco de dados cursor_sharing. Quando definido como "force", ele modificará todas as instruções SQL. Todas as "constantes" nas consultas serão substituídas por variáveis de ligação (como 1 => :SYS_0).
Esta opção foi introduzida para lidar com alguns desenvolvedores preguiçosos. Por outro lado, também pode prejudicar outros desenvolvedores preguiçosos. Mas o risco não é muito alto. Desde 11g, ele possui o recurso de espreitadela variável de ligação.