Dada esta pregunta en reddit, limpié la consulta para señalar dónde estaba el problema en la consulta. Utilizo comas primero y WHERE 1=1
para facilitar la modificación de consultas, por lo que mis consultas generalmente terminan así:
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
Básicamente, alguien dijo que 1 = 1 es generalmente flojo y malo para el rendimiento .
Dado que no quiero "optimizar prematuramente", sí quiero seguir buenas prácticas. He visto los planes de consulta antes, pero generalmente solo para averiguar qué índices puedo agregar (o ajustar) para que mis consultas se ejecuten más rápido.
La pregunta entonces realmente ... ¿hace Where 1=1
que sucedan cosas malas? Y si es así, ¿cómo puedo saberlo?
Edición menor: siempre he 'asumido' que eso 1=1
se optimizaría o, en el peor de los casos, sería insignificante. Nunca está de más cuestionar un mantra, como "Goto's are Evil" u "Optimización prematura ..." u otros hechos supuestos. No estaba seguro si 1=1 AND
afectaría de manera realista los planes de consulta o no. ¿Qué pasa en subconsultas? CTE? Procedimientos?
No soy uno para optimizar, a menos que sea necesario ... pero si estoy haciendo algo que es realmente "malo", me gustaría minimizar los efectos o cambiarlos cuando corresponda.
fuente
Respuestas:
El servidor SQL
analizadorEl optimizador tiene una característica llamada "Plegado constante" que elimina las expresiones tautológicas de la consulta.Si observa el plan de ejecución, en ninguna parte de los predicados verá aparecer esa expresión. Esto implica que el plegado constante se realiza de todos modos en el momento de la compilación por esta y otras razones y no tiene ningún efecto en el rendimiento de la consulta.
Consulte Evaluación de plegado constante y expresión durante la estimación de cardinalidad para obtener más información.
fuente
La adición del predicado redundante puede marcar la diferencia en SQL Server.
En los planes de ejecución a continuación, observe el
@1
en el primer plan frente al literal'foo'
en el segundo plan.Esto indica que SQL Server consideró la primera consulta de parametrización simple para promover la reutilización del plan de ejecución; sin embargo, la comparación de dos constantes evita que esto suceda en el segundo caso.
Se puede encontrar una lista de condiciones que evitan la parametrización simple (anteriormente conocida como autoparamización de parámetros) en el Apéndice A de los documentos técnicos del plan de almacenamiento en caché de Microsoft:
Sin embargo, la parametrización simple generalmente no es algo en lo que deba confiar. Es mucho mejor parametrizar explícitamente sus consultas.
fuente
En cualquier RDBMS moderno (incluidos Oracle, Microsoft SQL Server y PostgreSQL, estoy seguro de esto), esto no tendrá ningún efecto en el rendimiento.
Como alguien señaló, esto afectará solo la fase de planificación de consultas. Por lo tanto, la diferencia será visible solo cuando ejecute miles de iteraciones de una consulta simplista que no devuelva ningún dato, como este:
Para mí, en PostgreSQL 9.0, esto es visible con solo 10000 iteraciones:
fuente
Esto puede ser un "problema" para Oracle cuando utiliza el parámetro de base de datos cursor_sharing. Cuando esto se establece en "forzar", modificará todas las instrucciones SQL. Todas las "constantes" en las consultas serán reemplazadas por variables de enlace (como 1 =>: SYS_0).
Esta opción se introdujo para tratar con algunos desarrolladores perezosos. Por otro lado, también puede dañar a otros desarrolladores perezosos. Pero el riesgo no es demasiado alto. Desde 11g tiene una función de lectura variable variable de enlace.
fuente