2009-07-08 16 views
6

Prefiero codificar en t-sql usando lo que en realidad es una unión en línea, en lugar de tener una lista larga de las uniones al final del procedimiento o vista almacenada.¿Cuál de las dos formas de codificar una unión interna es más rápida?

Por ejemplo, el código I:

SELECT  PKey , Billable, 
    (SELECT LastName FROM Contact.dbo.Contacts WHERE (Pkey = Contacts_PKey)), 
    (SELECT Description FROM Common.dbo.LMain WHERE (PKey= DType)), 
    (SELECT TaskName FROM Common.dbo.LTask WHERE (PKey = TaskType)) , 
    StartTime, EndTime, SavedTime 
FROM dbo.TopicLog where StartTime > '7/9/09' ORDER BY StartTime 

En lugar de

SELECT t.PKey, t.Billable, c.LastName, m.Description, lt.TaskName, t.StartTime, t.EndTime, t.SavedTime 
FROM dbo.TopicLog AS t  
inner join Contact.dbo.Contacts as c on c.Pkey = t.Contacts_PKey and t.StartTime > '7/9/09' 
inner join Common.dbo.LMain as m on m.PKey = t.DType 
inner join Common.dbo.LTask as lt on lt.PKey = t.TaskType 
ORDER BY t.StartTime 

prefiero este tipo de sintaxis, ya que es mucho menos confuso al escribir o depuración, especialmente cuando hay muchas mesas siendo unidas u otras cosas pasando (declaraciones de casos, funciones t-sql, autocombinaciones, etc.)

Pero mi pregunta es: estoy teniendo un golpe de rendimiento al consultar el databa se de esta manera.

No tengo suficientes datos recopilados para poder medir la diferencia, pero lo haré en algún momento.

Me gustaría averiguarlo antes de continuar. No me gustaría tener que volver más tarde y recodificar todo para mejorar el rendimiento.

Respuesta

20

El segundo (la unión interior real), generalmente. El primero (subconsultas) realiza 3 consultas para cada fila, pero esto generalmente es administrado por el compilador para que las diferencias se mitiguen.

Mejor aún: Check the query execution plans para usted!

Dado que obtiene un rendimiento lento, supongo que sus tablas no están indexadas correctamente. Debería tener índices agrupados en todas sus claves principales e índices no agrupados en las claves externas (las que usa para formar las uniones).

Debo notar que estas dos consultas son equivalentes si y solo si tienes valores coincidentes en todas tus condiciones de unión (es decir, siempre devuelve todas las filas de la tabla principal). De lo contrario, obtendrá null de la sub consulta si no hay coincidencia. Las combinaciones internas filtran activamente las filas que no coinciden con las condiciones de unión. El enfoque de subconsulta es en realidad equivalente (en resultados, no en velocidad o ejecución) a una combinación externa izquierda.

+1

+1. Como usted señala, es mucho más probable que las ganancias que se obtienen de una indexación cuidadosa produzcan ganancias significativas. (¡Pero verificar el plan de ejecución les hará saber con certeza!) – Beska

+2

+1 "¡Compruebe los planes de ejecución de consultas por usted mismo!" Esa es la única forma de estar seguro. El optimizador * podría * convertirlos en JOINs automáticamente. Aunque, las dos consultas no son exactamente lo mismo. # 1 es un LEFT JOIN, # 2 es un INNER JOIN. Entonces te darán diferentes planes de todos modos. – beach

+0

Esto es bastante engañoso: es un concepto erróneo común que las subconsultas son más lentas por la razón que usted ha dado, donde de hecho el servidor SQL reescribe las subconsultas como uniones cuando sea posible de todos modos durante la recompilación. – Justin

0

En general las subconsultas (es decir, el primer ejemplo) son más lentas, pero la forma más fácil de optimizar y analizar sus consultas es probarlas a través de su base de datos específica. El servidor MS SQL proporciona excelentes herramientas de análisis y ajuste del rendimiento.

+0

Eso es simplemente falso: a menudo SQL Server analiza las subconsultas en un árbol de ejecución que es idéntico al producido por una unión. – Justin

10

El primer método no es una combinación interna en absoluto, es una subconsulta correlacionada. Y son más como uniones externas izquierdas que uniones internas, ya que devolverán valores NULL cuando no haya un valor coincidente.

3

La primera parece una forma patológica de unirse a mí. Lo evitaría, si por alguna otra razón no es inusual, un DBA SQL experimentado que lo mire para mantenerlo pasará un rato buscando la razón de por qué está codificado así, cuando no hay una razón real en cuanto a lo que quiero la consulta que hacer. Se comporta más como una combinación externa si faltan datos.

El segundo ejemplo parece normal.

Usted debe saber que el camino de la vieja escuela de hacer las combinaciones internas es así:

SELECT t.PKey, t.Billable, 
c.LastName, m.Description, lt.TaskName, 
t.StartTime, t.EndTime, t.SavedTime 
FROM 
dbo.TopicLog as t, Contact.dbo.Contacts as c, 
Common.dbo.LMain as m, Common.dbo.LTask as lt 
WHERE c.Pkey = t.Contacts_PKey and t.StartTime > '7/9/09' 
    AND m.PKey = t.DType 
    AND lt.PKey = t.TaskType 
ORDER BY t.StartTime 

Y a ojo esto es equivalente a la moderna "unión interna mesa en campo" Sintaxis una vez que ha sido analizado.

Como dice la otra respuesta, si busca consultas más rápidas, lo primero que debe hacer es verificar que los índices de las tablas estén ordenados. Luego mira el plan de ejecución de consulta.

+0

Parece que esta sintaxis es lo que él busca. Los índices o no índices que realizan subconsultas para cada tabla de filas que se seleccione van a ser lentos incluso para una tabla pequeña (como más de 4000 filas). – Jon

0

Muchos programadores de SQL no saben que el optimizador resuelve frecuentemente las subconsultas en combinaciones. Es probable que no haya motivos para problemas de rendimiento en ninguna de las consultas.

Ver el plan de ejecución!

1

Las dos consultas en el OP dicen cosas muy diferentes y sólo producen los mismos resultados si los correctos los supuestos del modelo de datos están en su lugar:

  1. Cada una de las columnas utilizadas en las operaciones de búsqueda tienen limitaciones no nulos y restricciones de clave externa.

  2. Se utiliza la clave principal o una clave única de la tabla de búsqueda.

puede ser en el caso específico OP estas suposiciones son verdaderas, pero en el caso general éstos son diferentes.

Como han señalado otros, la consulta secundaria es más parecida a una combinación externa ya que devolverá un valor nulo para las columnas Apellido, Descripción y Nombre de tarea en lugar de filtrar la fila por completo.

Además, si una de las subconsultas devuelve más de una fila, obtendrá un error.

En cuanto a preferencia personal, prefiero el segundo ejemplo con la sintaxis de unión, pero eso es subjetivo.

0

Creo que el segundo es ejecutar más rápido. La razón detrás de esto es mediante el uso de alias (t, c, m, etc. en su ejemplo) el motor relacional de nombres puede encontrar fácilmente el puntero a la ubicación de la tabla.

Creo que este es uno de los consejos en el ajuste de sql.

1

En términos generales existe ninguna diferencia en el desempeño de sub consultas simples vs une - es un error común que subconsultas son mucho más lentos (porque el servidor SQL tiene que recorrer la consulta interna), sin embargo en términos generales esto es simplemente falso! Durante el proceso de compilación, el servidor SQL produce un árbol de ejecución y, a menudo, en estas árboles, las subconsultas equivalen a combinaciones.

Vale la pena señalar que sus dos consultas no son lógicamente la misma y producen resultados diferentes para mí, la segunda consulta en realidad debería decir algo en la línea de: (esto todavía isnt idénticos, pero está más cerca)

SELECT t.PKey, t.Billable, c.LastName, m.Description, lt.TaskName, t.StartTime, t.EndTime, t.SavedTime 
FROM dbo.TopicLog AS t  
LEFT OUTER JOIN Contact.dbo.Contacts as c on c.Pkey = t.Contacts_PKey 
LEFT OUTER JOIN Common.dbo.LMain as m on m.PKey = t.DType 
LEFT OUTER JOIN Common.dbo.LTask as lt on lt.PKey = t.TaskType 
WHERE t.StartTime > '7/9/09' 
ORDER BY t.StartTime 

En mi prueba, la subconsulta produjo un plan de ejecución con un número de lecturas significativamente menor (15 en comparación con 1000), sin embargo, una CPU ligeramente superior: en promedio, los tiempos de ejecución fueron más o menos equivalentes.

Sin embargo, vale la pena señalar que esto no siempre será el caso (especialmente cuando se evalúan las funciones dentro de una subconsulta), y veces puede tener problemas debido a una subconsulta. En términos generales, sin embargo, es mejor preocuparse por estos casos solo cuando se encuentre con problemas de rendimiento.

Cuestiones relacionadas