2009-09-09 22 views
21

Tengo una consulta relativamente simple que une dos tablas. Los criterios "Dónde" se pueden expresar en los criterios de unión o como cláusula where. Me pregunto cuál es más eficiente.Criterios de filtro SQL en criterios de unión o cláusula where que es más eficiente

La búsqueda consiste en encontrar las ventas máximas para un vendedor desde el principio de los tiempos hasta su promoción.

Caso 1

select salesman.salesmanid, max(sales.quantity) 
from salesman 
inner join sales on salesman.salesmanid =sales.salesmanid 
        and sales.salesdate < salesman.promotiondate 
group by salesman.salesmanid 

Caso 2

select salesman.salesmanid, max(sales.quantity) 
from salesman 
inner join sales on salesman.salesmanid =sales.salesmanid 
where sales.salesdate < salesman.promotiondate 
group by salesman.salesmanid 

caso de la nota 1 carece de una cláusula que, en conjunto

RDBMS es SQL Server 2005

EDITAR Si el segundo Pieza de el criterio de unión o la cláusula where fue sales.salesdate < una fecha fija, por lo que no es ningún criterio de unión de las dos tablas, eso cambia la respuesta.

+0

¿Qué hay de malo con realmente probar el tiempo que tardan estas consultas? – ChristopheD

+2

Porque la consulta se almacena en caché, pero gracias, realmente – Gratzy

+1

@Gratzy - DBCC FREEPROCCACHE http://msdn.microsoft.com/en-us/library/ms174283.aspx –

Respuesta

20

No utilizaría el rendimiento como el factor decisivo aquí, y sinceramente, no creo que haya ninguna diferencia de rendimiento mensurable entre esos dos casos, realmente.

Siempre usaría el estuche # 2 - ¿por qué? Porque, en mi opinión, solo debe poner los criterios reales que establecen el JOIN entre las dos tablas en la cláusula JOIN - todo lo demás pertenece a la cláusula WHERE.

Solo una cuestión de mantener las cosas limpias y poner las cosas donde pertenecen, IMO.

Obviamente, hay casos con UNIONES EXTREMAS IZQUIERDAS donde la colocación de los criterios hace una diferencia en términos de los resultados que se devuelven; esos casos se excluirán de mi recomendación, por supuesto.

Marc

+1

+1 - buena respuesta marc –

+0

IMO se podría argumentar que el caso # 1 es mejor para la encapsulación (en este caso, la cláusula WHERE solo se usa para los criterios de la tabla principal). –

0

Puede parecer frívolo, pero la respuesta es la consulta para la que el analizador de consultas produce el plan más eficiente.

En mi opinión, parecen ser equivalentes, por lo que el analizador de consultas puede producir planes idénticos, pero tendría que probar.

0

Ni es más eficiente, utilizando el método en el que se considera la vieja manera de hacerlo (http://msdn.microsoft.com/en-us/library/ms190014.aspx). Puedes mirar el plan de ejecución y ver que hagan lo mismo.

+0

Mi ejemplo no fue el mejor cambio la segunda parte de la cláusula join y o where para ser una fecha fija en lugar de una fecha en la tabla del vendedor. – Gratzy

+0

Ahh bien, bien en cualquier caso, el Plan de ejecución es tu amigo. Analízalo para encontrar cuál tiene el mejor rendimiento. Mi apuesta es que serán idénticos. –

1

No creo que encuentres una respuesta finita para esta que se aplique a todos los casos. Los 2 no siempre son intercambiables, ya que para algunas consultas (algunas combinaciones a la izquierda) se obtendrán resultados diferentes al colocar los criterios en la línea DONDE vs la línea DE.

En su caso, debe evaluar estas dos consultas. En SSMS, puede ver los planes de ejecución reales y estimados de ambas consultas; ese sería un buen primer paso para determinar cuál es más óptimo. También puede ver el tiempo & IO para cada uno (establecer el tiempo de las estadísticas activado, configurar estadísticas io encendido), y eso también le dará información para tomar su decisión.

En el caso de las consultas en su pregunta, apostaría a que ambos saldrán con el mismo plan de consulta, por lo que en este caso puede que no importe, pero en otros podría generar diferentes planes.

probar este para ver la diferencia entre el 2 ...

SET STATISTICS IO ON 
SET STATISTICS TIME ON 

select salesman.salesmanid, 
     max(sales.quantity) 
from salesmaninner join sales on salesman.salesmanid =sales.salesmanid 
     and sales.salesdate < salesman.promotiondate 
group by salesman.salesmanid 

select salesman.salesmanid, 
     max(sales.quantity) 
from salesmaninner join sales on salesman.salesmanid = sales.salesmanid 
where sales.salesdate < salesman.promotiondate 
group by salesman.salesmanid 

SET STATISTICS TIME OFF 
SET STATISTICS IO OFF 
+0

Esto sería específicamente combinaciones internas – Gratzy

+1

Gratzy - en ese caso, estoy de acuerdo con marc_s - los criterios de filtro deben mantenerse en la parte WHERE de la consulta, y los criterios de unión deben mantenerse en la parte FROM de la consulta. –

+0

¿Importa sin embargo que la tabla de criterios where tenga muchas, muchas filas más? Sé que puede sonar trivial, pero me preguntaba si sería mejor incluirlo en los criterios de unión en lugar de la cláusula where – Gratzy

0

familiarizarse con el plan de ejecución estimado en Management Studio de SQL !! Como han dicho otros, está a merced del analizador sin importar lo que haga, así que confíe en sus estimaciones. Supongo que los dos que proporcionaste producirán exactamente el mismo plan.

Si se trata de un intento de cambiar una cultura de desarrollo, elija la que le ofrezca un mejor plan; para los que son idénticos, siga la cultura

He comentado esto en otras publicaciones de "eficiencia" como esta (es sincero y sarcástico) - si es aquí donde residen sus cuellos de botella, entonces de cinco a usted y su equipo

+1

Sí, estoy familiarizado con el Plan de ejecución estimado. Sin embargo, no me dirá por qué genera el plan de ejecución de la forma en que lo hace. Estaba buscando entender por qué uno podría ser más eficiente que el otro. – Gratzy

+0

@Gratzy: http://www.amazon.com/Gurus-Guide-Server-Architecture-Internals/dp/0201700476 –

3

Prefiero tener cualquier criterio codificado en la unión. Hace que SQL sea mucho más legible y portátil.

Legibilidad: Puede ver exactamente qué datos va a obtener porque todos los criterios de la tabla están escritos allí en la unión. En declaraciones grandes, los criterios pueden estar ocultos dentro de otras 50 expresiones y se pueden perder fácilmente.

Portabilidad: Puede copiar un fragmento de la cláusula FROM y pegarlo en otro lugar. Eso le da las uniones y cualquier criterio que necesite para lograrlo. Si siempre usa ese criterio al unir esas dos tablas, ponerlo en la unión es lo más lógico.

Por ejemplo:

FROM 
table1 t1 
JOIN table2 t2_ABC ON 
    t1.c1 = t2_ABC.c1 AND 
    t2_ABC.c2 = 'ABC' 

Si usted necesita para obtener una segunda columna de la tabla 2 que acaba de copiar ese bloque en el Bloc de notas, buscar/repalce "ABC" y listo y todo nuevo bloque de código listo para volver a pegar.

Adicional: También es más fácil cambiar entre una combinación interna y externa sin tener que preocuparse por ningún criterio que pueda estar flotando en la cláusula WHERE.

Reservo la cláusula WHERE estrictamente para criterios de tiempo de ejecución donde sea posible.

En cuanto a la eficiencia: Si se refiere a la velocidad de ejecución, entonces, como todos han dicho, es redundante. Si se refiere a la depuración y reutilización más fácil, entonces yo prefiero la opción 1.

+0

En resumen, los criterios en el JOIN son mejores para la encapsulación, y la encapsulación aumentada es generalmente mejor. –

1

Una cosa que quiero decir, finalmente, como me notificó, antes de eso .. Ambas formas pueden dar el mismo rendimiento o el uso de los criterios de Donde cláusula puede ser un poco más rápido como se encuentra en algunas respuestas ..

Pero he identificado una diferencia, se puede utilizar para sus necesidades lógicas ..

  1. Utilizando los criterios en EN cláusula no filtrará/saltar las filas para seleccionar lugar la unión columnas serían nulas basado en las condiciones

  2. Utilizando los criterios en Dónde cláusula puede filtrar/omitir las filas en la totalidad de los resultados

0

El caso 1 (criterios en el JOIN) es mejor para la encapsulación, y una mayor encapsulación suele ser una buena cosa: disminuyó las omisiones de copiar/pegar a otra consulta, disminuyó errores si más tarde se convirtió a LEFT JOIN y mejor legibilidad (cosas relacionadas y menos "ruido" en la cláusula WHERE). En este caso, la cláusula WHERE solo captura los criterios o criterios de la tabla principal que abarcan varias tablas.

Cuestiones relacionadas