Bueno, malo o indiferente: DONDE 1 = 1

14

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=1para 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=1que sucedan cosas malas? Y si es así, ¿cómo puedo saberlo?

Edición menor: siempre he 'asumido' que eso 1=1se 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 ANDafectarí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.

WernerCD
fuente
2
No, no lo haría. Aparte de unos pocos microsegundos para que el optimizador elimine la condición redundante. Es mejor que te enfoques en que tus literales de citas no sean ambiguos.
ypercubeᵀᴹ
Como dijo @ypercube, no hay diferencia. El optimizador de consultas tendría que ser un pedazo de mierda para que tal cosa haga alguna diferencia;)
Philᵀᴹ
44
No creas todo lo que lees en reddit. Por favor.
Aaron Bertrand
1
@AaronBertrand Tomo todo con un grano de sal, hasta que lo experimenté de primera mano. Todavía tomaré una pregunta que suene plausible y veré si hay algo de verdad en ella, especialmente cuando afecta mi trabajo diario.
WernerCD 01 de
44
Hay granos de sal, luego está el contenido de sal de un océano entero arrojado sobre el edificio de su oficina: P
Phil

Respuestas:

13

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.

spaghettidba
fuente
Probablemente se haya compilado porque este es un patrón conocido para hacer la concatenación de campos.
jcolebrand
No, está compilado porque es tautológico. Funcionaría de la misma manera con 2736 = 2736, que no es tan habitual como 1 = 1. Lo mismo se aplica a las contradicciones. En ese caso, la función se llama "Detección de contradicciones".
spaghettidba
¿Qué parte del "patrón conocido" significa "tiene que ser 1 = 1"?
jcolebrand
9

La adición del predicado redundante puede marcar la diferencia en SQL Server.

En los planes de ejecución a continuación, observe el @1en el primer plan frente al literal 'foo'en el segundo plan.

ingrese la descripción de la imagen aquí

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.

Martin Smith
fuente
4

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:

SELECT 1 FROM empty_table; -- run this 10 000 times.

SELECT 1 FROM empty_table WHERE 1=1; -- run this 10 000 times and compare.

Para mí, en PostgreSQL 9.0, esto es visible con solo 10000 iteraciones:

filip@srv:~$ pgquerybench.pl -h /var/run/postgresql/ -q "select 1 from never where 1=1" -q "select 1 from never" -i 10000
Iterations: 10000
Query:   select 1 from never where 1=1
Total:   2.952 s
Average: 0.295 ms
Query:   select 1 from never
Total:   2.850 s
Average: 0.285 ms
filiprem
fuente
0

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.

ibre5041
fuente
¿Puede aclarar qué "desde 11g tiene la función de vinculación variable de enlace". ¿medio?
ypercubeᵀᴹ
@ypercube "Análisis de variables de enlace" significa que el optimizador observará los valores reales de las variables de enlace y usará estadísticas de datos para reevaluar y posiblemente regenerar el plan de ejecución de la consulta. Sin embargo, dudo que echar un vistazo tenga algún efecto en la construcción que se está discutiendo, ya que no depende de las estadísticas de datos.
mustaccio