2009-06-26 13 views
17

Para mis consultas SQL, por lo general hacer lo siguiente para las instrucciones SELECT:T-SQL 1 = 1 Rendimiento Hit

SELECT ... 
FROM table t 
WHERE 1=1 
    AND t.[column1] = @param1 
    AND t.[column2] = @param2 

Esto hará más fácil si tengo que añadir/eliminar/comentar ninguna cláusula WHERE, ya que no tengo que preocuparme por la primera línea.

¿Hay algún golpe de rendimiento al usar este patrón?

Información adicional:

Ejemplo para sheepsimulator y todos los demás que no recibieron el uso.

supongamos que la consulta anterior, tengo que cambiar @ param1 que no está incluido en la consulta:

Con 1 = 1:

... 
WHERE 1=1 <-- no change 
    --AND t.[column1] = @param1 <-- changed 
    AND t.[column2] = @param2 <-- no change 
... 

Sin 1 = 1:

... 
WHERE <-- no change 
    --t.[column1] = @param1 <-- changed 
    {AND removed} t.[column2] = @param2 <-- changed 
... 
+1

Lo siento si esto suena un poco daff, pero realmente no estoy seguro de cómo Addding 1 = 1 a la cláusula WHERE que obtiene los beneficios anteriores; ¿Podrían dar más detalles sobre esto para aquellos de nosotros que quisiéramos aprender esta posible mejor práctica? –

+0

@sheepsimulator: es muy fácil de comentar y elimine cualquier condición simplemente anteponiendo con doble guión (-) – Quassnoi

+2

Hola Adrian, siempre hacen lo mismo, es tan cómodo para construir consultas dinámicas ... – tekBlues

Respuesta

11

Es probable que si utiliza el generador de perfiles y la apariencia, termine viendo que el optimizador terminará ignorando eso más de las veces, por lo que en el gran esquema de cosas, probablemente no habrá mucho en el camino de performanc e ganancia o pérdidas.

+1

estoy de acuerdo. @ Adrian: si escribe las dos consultas juntas y activa el plan de ejecución, probablemente verá que ambas consultas son 50% cada una. – RichardOD

1

Sin golpe de rendimiento. Incluso si su cláusula WHERE está cargada con una gran cantidad de comparaciones, esto es muy pequeño.

mejor de los casos es que se trata de una comparación bit a bit. Peor aún es que los dígitos se evalúan como enteros.

17

No, SQL Server es lo suficientemente inteligente como para omitir esta condición desde el plan de ejecución, ya que siempre es TRUE.

Lo mismo es cierto para Oracle, MySQL y PostgreSQL.

+0

¿Tiene una fuente para esto? Te creo, solo vincularé algo para referenciar. –

+0

@Danny: para MySQL, sí: http://dev.mysql.com/doc/refman/5.6/en/where-optimizations.html * Eliminación condición constante (necesario debido a plegado constante) *, para otros no, pero constante plegado es característica núcleo de cualquier optimizador – Quassnoi

1

Para consultas de cualquier complejidad razonable no habrá diferencia. Puede ver algunos planes de ejecución y también comparar los costos reales de ejecución y comprobarlo usted mismo.

2

No hay diferencia, ya que evaluaron constantes y están optimizados. Utilizo tanto 1 = 1 como 0 = 1 en las listas generadas a mano y en código AND y OR y no tiene ningún efecto.

3

Esto no tiene ningún impacto en el rendimiento, pero no se ve el texto SQL como ha sido mutilado por un ataque de inyección SQL. El truco '1 = 1' aparece en muchos ataques basados ​​en inyección sql. Simplemente corre el riesgo de que algún cliente suyo implemente algún día una 'caja negra' que monitoree el tráfico SQL y verá que su aplicación está marcada como 'pirateada'. También los analizadores de código fuente pueden marcar esto. Es un tiro largo, por supuesto, pero algo vale la pena poner en la balanza.

+0

un truco fresco, pero este es un punto válido. Puedo comenzar a usar esto durante el desarrollo, pero me gustaría quitarlo antes de lanzarlo a producción. –

+5

No es un punto válido que diría. La inyección SQL usa "OR 1 = 1", no "1 = 1 AND". Esos dos son claramente diferentes, si una aplicación no puede diferenciarlos, ¿está seguro de que los otros resultados son confiables? Si su –

+0

hacer esto en una aplicación web o el sistema SAAS el cliente probablemente no es capaz de instalar sus propias herramientas de monitoreo. Y, por supuesto, si instala el suyo, sabe que estas consultas son seguras. – danielson317

2

Como la condición siempre es verdadera, SQL Server la ignorará. Puede verificar ejecutando dos consultas, una con la condición y otra sin, y comparando los dos planes de ejecución reales.

Una alternativa para lograr su facilidad de comentar requisito es la reestructuración de su consulta:

 
SELECT ... 
FROM table t 
WHERE 
    t.[column1] = @param1 AND 
    t.[column2] = @param2 AND 
    t.[column3] = @param3 

A continuación, puede añadir/eliminar/comentar las líneas en las condiciones en las que y es todavía será SQL válida.

+1

Agregar una línea requerirá la modificación de la última línea. –

+2

sí ... a menos que no lo agregue como la última línea :) – adrianbanks

0

Una de las consecuencias potencialmente ligeramente negativo de esto es que el AND 1=1 dejará de instalación de SQL Server simple parameterisation de patadas en.

guión de demostración

DBCC FREEPROCCACHE; /*<-- Don't run on production box!*/ 

CREATE TABLE [E7ED0174-9820-4B29-BCDF-C999CA319131] 
(
X INT, 
Y INT, 
PRIMARY KEY (X,Y) 
); 

GO 
SELECT * 
FROM [E7ED0174-9820-4B29-BCDF-C999CA319131] 
WHERE X = 1 
     AND Y = 2; 
GO 
SELECT * 
FROM [E7ED0174-9820-4B29-BCDF-C999CA319131] 
WHERE X = 2 
     AND Y = 3; 
GO 
SELECT * 
FROM [E7ED0174-9820-4B29-BCDF-C999CA319131] 
WHERE 1 = 1 
     AND X = 1 
     AND Y = 2 
GO 
SELECT * 
FROM [E7ED0174-9820-4B29-BCDF-C999CA319131] 
WHERE 1 = 1 
     AND X = 2 
     AND Y = 3  

SELECT usecounts, 
     execution_count, 
     size_in_bytes, 
     cacheobjtype, 
     objtype, 
     text, 
     creation_time, 
     last_execution_time, 
     execution_count 
FROM sys.dm_exec_cached_plans a 
     INNER JOIN sys.dm_exec_query_stats b 
     ON a.plan_handle = b.plan_handle 
     CROSS apply sys.dm_exec_sql_text(b.sql_handle) AS sql_text 
WHERE text LIKE '%\[E7ED0174-9820-4B29-BCDF-C999CA319131\]%' ESCAPE '\' 
     AND text NOT LIKE '%this_query%' 
ORDER BY last_execution_time DESC  

GO 

DROP TABLE [E7ED0174-9820-4B29-BCDF-C999CA319131] 

muestra que tanto las consultas sin la 1=1 fueron satisfechas por una única versión parametrizado del plan almacenado en caché, mientras que las consultas con el 1=1 compiló y almacenó un plan separado para los diferentes valores constantes.

enter image description here

Lo ideal es que no se debe confiando en esto de todos modos y aunque se debe parametrizar explícitamente consultas para asegurar que los elementos deseados son parametrizar y los parámetros tienen los tipos de datos correctos.

Cuestiones relacionadas