2009-06-16 17 views
6

En mi base de datos MS SQL Server estoy extrayendo datos de transacciones basados ​​en una variedad de códigos diferentes que están en una columna.SQL CASE vs JOIN efficiency

sería más eficiente para:

  • se unen a la misma mesa una y otra vez para cada código en una cláusula WHERE

  • hacer múltiples declaraciones de caso sobre toda la tabla (que se muestra a continuación)

  • hacer múltiples declaraciones de caso sobre toda la mesa, pero la limitan por una cláusula WHERE SubsidCde IN ('AA','BA','BB', etc)

Tenemos tantas consultas ejecutándose por segundo que, aunque he probado los 3 métodos, no obtengo resultados definitivos.

SELECT 
    SUM(CASE WHEN Subsid_Cde = 'AA' THEN Trans_Amt END),0) [AA], 
    SUM(CASE WHEN Subsid_Cde = 'BA' THEN Trans_Amt END),0) [BA], 
    SUM(CASE WHEN Subsid_Cde = 'BB' THEN Trans_Amt END),0) [BB] 
FROM 
    Transactions 

-- There are 8 more rows like this, using a different code for each line 
+0

Consulte http://sqlblog.com/blogs/linchi_shea/archive/2011/04/04/performance-impact-the-cost-of-doing-small-lookups-in-a-large-batch.aspx –

Respuesta

3

Si está sumando Todos los posibles (o la mayoría) de los valores de campo Subsid_Cde, entonces CASE es más rápido, ya que no explorará la mesa varias veces, puesto que agrega las sumas Si solo busca un pequeño subconjunto de posibles campos Subsid_Cde, las selecciones/uniones separadas (junto con un índice en Subsid_Cde) funcionarán más rápido.

Tiene que aprender a leer los Planes de ejecución, entonces podrá resolverlos usted mismo.

También, alternativamente, se puede hacer un GROUP BY en Subsid_Cde envuelto en una cláusula de pivote (Google por PIVOT MS SQL Server 2005)

1

Utilice esta:

SELECT (
     SELECT SUM(Trans_Amt) 
     FROM Transactions 
     WHERE Subsid_Cde = 'AA' 
     ) AS sum_aa, 
     (
     SELECT SUM(Trans_Amt) 
     FROM Transactions 
     WHERE Subsid_Cde = 'BB' 
     ) AS sum_bb 

, sin cláusula externo FROM o WHERE.

En SQL Server 2005+, utilice esto:

SELECT [AA], [BB] 
FROM (
     SELECT trans_amt, subsid_cde 
     FROM transactions 
     ) q 
PIVOT (
     SUM(trans_amt) 
     FOR subsid_cde IN (['AA'], ['BB']) 
     ) 
2

3 es la mejor opción. Es fácil de leer, es fácil de modificar más adelante, y debe usar los índices que ha definido y espera usar (aún, verifique).

--1 A veces tiene que unirse a la misma mesa. Pero este no es uno de ellos y unirse cada vez que necesite incluir un nuevo Subsid_Cde genera un SQL menos legible sin realmente obtener nada.

--2 Las tablas de transacción tienden a crecer muy grandes, por lo que NUNCA desea escanear toda la tabla. Así que el # 2 está definitivamente fuera, a menos que los códigos que usará en su consulta le devuelvan todas las filas de todos modos.