Dada essa pergunta no reddit, limpei a consulta para apontar onde estava o problema na consulta. Uso vírgula primeiro e WHERE 1=1
para facilitar a modificação de consultas, de modo que minhas consultas geralmente acabam 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 .
Como não quero "otimizar prematuramente" - quero seguir boas práticas. Analisei os planos de consulta antes, mas geralmente apenas para descobrir quais índices posso adicionar (ou ajustar) para fazer com que minhas consultas sejam executadas mais rapidamente.
A questão então realmente ... faz Where 1=1
com que coisas ruins aconteçam? E se sim, como posso saber?
Edição menor: Eu sempre 'assumi' que 1=1
seria otimizado ou, na pior das hipóteses, seria insignificante. Nunca é demais questionar um mantra, como "Goto é mau" ou "Otimização prematura ..." ou outros fatos assumidos. Não tinha certeza se 1=1 AND
isso 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 estou fazendo algo que é realmente "ruim", gostaria de minimizar os efeitos ou alterar, quando aplicável.
fonte
Respostas:
O SQL Server
analisadorO otimizador possui um recurso chamado "Dobragem constante" que elimina expressões tautológicas da consulta.Se você observar o plano de execução, em nenhum lugar dos predicados verá a expressão aparecer. Isso implica que a dobragem constante é realizada de qualquer maneira no tempo de compilação por esse e outros motivos e não afeta o desempenho da consulta.
Consulte Avaliação constante das expressões e dobras durante a estimativa de cardinalidade para obter mais informações.
fonte
A adição do predicado redundante pode fazer a 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 para parametrização simples para promover a reutilização do plano de execução - no entanto, 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 parametrização automática) pode ser encontrada no Apêndice A dos Documentos Técnicos da Microsoft de Cache do Plano:
parametrização simples geralmente não é algo em que você deva confiar, de qualquer maneira. É muito melhor parametrizar explicitamente suas consultas.
fonte
Em qualquer RDBMS moderno (incluindo Oracle, Microsoft SQL Server e PostgreSQL - tenho certeza sobre isso), 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 10000 iterações:
fonte
Isso pode ser "problema" para o Oracle quando você usa o parâmetro cursor_sharing do banco de dados. Quando definido como "force", ele modifica 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 o 11g, ele tem o recurso de espreitar variável.
fonte