2008-09-22 21 views
11

Tengo dos tablas que contienen Tareas y Notas, y quiero recuperar una lista de tareas con el número de notas asociadas para cada una. Estas dos consultas hacen el trabajo:Transact-SQL - ¿sub consulta o left-join?

select t.TaskId, 
     (select count(n.TaskNoteId) from TaskNote n where n.TaskId = t.TaskId) 'Notes' 
from Task t 

-- or 
select t.TaskId, 
     count(n.TaskNoteId) 'Notes' 
from Task t 
left join 
     TaskNote n 
on  t.TaskId = n.TaskId 
group by t.TaskId

¿Hay una diferencia entre ellos y que deben estar usando uno sobre el otro, o son sólo dos formas de hacer el mismo trabajo? Gracias.

Respuesta

12

En pequeños conjuntos de datos, se lavan cuando se trata de rendimiento. Cuando se indexa, el LOJ es un poco mejor.

He encontrado en grandes conjuntos de datos que una unión interna (una unión interna también funcionará) superará a la subconsulta por un factor muy grande (lo siento, no hay números).

+0

ídem en la unión interna - He visto que hace una gran diferencia en el conjunto grande (suponiendo que es el comportamiento correcto que desea, y es posible que necesite usar un ISNULL() o una función similar) –

0

Puede usar cualquiera de ellos, y son semánticamente idénticos. En general, la regla de oro es usar cualquier forma que sea más fácil de leer, a menos que el rendimiento sea un problema.

Si el rendimiento es un problema, entonces experimente con la reescritura de la consulta utilizando la otra forma. Algunas veces el optimizador usará un índice para una forma, y ​​no para la otra.

1

No hay una respuesta clara sobre esto. Debería ver el Plan SQL. En términos de álgebra relacional, son esencialmente equivalentes.

6

En la mayoría de los casos, el optimizador los tratará de la misma manera.

Tiendo a preferir el segundo, porque tiene menos anidamiento, lo que hace que sea más fácil de leer y de mantener. Empecé a usar las expresiones de tabla comunes de SQL Server para reducir la anidación también por la misma razón.

Además, la segunda sintaxis es más flexible si hay más agregados que se pueden añadir en el futuro, además de contar, como MIN (some_scalar), MAX(), AVG() etc.

2

Si está utilizando SQL Server Management Studio, puede ingresar ambas versiones en el Query Editor y luego hacer clic derecho y seleccionar Visualizar plan de ejecución estimado. Le dará dos costos porcentuales relativos al lote. Si se espera que tarden el mismo tiempo, ambos se mostrarán como 50%, en cuyo caso, elija el que prefiera por otros motivos (más fácil de leer, más fácil de mantener, mejor ajustado a sus estándares de codificación, etc.). De lo contrario, puede elegir el que tenga el menor costo porcentual relativo al lote.

Puede usar la misma técnica para ver el cambio de cualquier consulta para mejorar el rendimiento al comparar dos versiones que hacen lo mismo.

Por supuesto, debido a que es un costo relativo al lote, no significa que cualquiera de las consultas sea tan rápida como podría ser: simplemente le indica cómo se comparan entre sí, no a alguna consulta óptima teórica para obtener los mismos resultados

5

La sub consulta será más lenta ya que se está ejecutando para cada fila en la consulta externa. La unión será más rápida ya que se realiza una vez. Creo que el optimizador de consultas no reescribirá este plan de consulta ya que no puede reconocer la equivalencia.

Normalmente harías una unión y agruparíarte para este tipo de conteo. Las subconsultas correlacionadas del tipo que muestra son principalmente de interés si tienen que hacer alguna agrupación o predicado más complejo en una tabla que no está participando en otra unión.

1

Me convierto en evitar las subconsultas siempre que sea posible. La unión generalmente será más eficiente.

Cuestiones relacionadas