Aplicación externa vs rendimiento de unión izquierda

37

Estoy usando SQL SERVER 2008 R2

Acabo de encontrar APLICAR en SQL y me encantó cómo resuelve los problemas de consulta en tantos casos,

Muchas de las tablas que estaba usando 2 left join para obtener el resultado, pude obtener 1 aplicación externa.

Tengo una pequeña cantidad de datos en mis tablas de bases de datos locales y, después de la implementación, se supone que el código se ejecuta en datos al menos 20 veces más grandes.

Me preocupa que la aplicación externa pueda llevar más tiempo que las 2 condiciones de unión restantes para una gran cantidad de datos,

¿Alguien puede decir cómo funciona exactamente aplicar y cómo afectará el rendimiento en datos muy grandes? Si es posible, algunas relaciones proporcionales con el tamaño de cada tabla son proporcionales a n1 ^ 1 o n1 ^ 2 ... donde n1 es el número de filas en la tabla 1)

Aquí está la consulta con 2 combinación izquierda

select EC.*,DPD.* from Table1 eC left join
  (
   select member_id,parent_gid,child_gid,LOB,group_gid,MAX(table2_sid) mdsid from Table2
   group by member_id,parent_gid,child_gid,LOB,group_gid

  ) DPD2 on DPD2.parent_gid = Ec.parent_gid
        AND DPD2.child_gid = EC.child_gid
        AND DPD2.member_id = EC.member_id
        AND DPD2.LOB = EC.default_lob
        AND DPD2.group_gid = EC.group_gid
  left join
  Table2 dpd on dpd.parent_gid = dpd2.parent_gid 
            and dpd.child_gid = dpd2.child_gid
            and dpd.member_id = dpd2.member_id 
            and dpd.group_gid = dpd2.group_gid 
            and dpd.LOB = dpd2.LOB
            and dpd.table2_sid = dpd2.mdsid

Aquí está la consulta con aplicación externa

select * from Table1 ec   
OUTER APPLY (
      select top 1 grace_begin_date,retroactive_begin_date,Isretroactive
                    from Table2 DPD 
                    where DPD.parent_gid = Ec.parent_gid
                    AND DPD.child_gid = EC.child_gid
                    AND DPD.member_id = EC.member_id
                    AND DPD.LOB = EC.default_lob
                    AND DPD.group_gid = EC.group_gid
                    order by DPD.table2_sid desc
     ) DPD 
Pratyush Dhanuka
fuente

Respuestas:

44

¿Alguien puede decir cómo funciona exactamente la aplicación y cómo afectará el rendimiento en datos muy grandes?

APPLYes una unión correlacionada (llamada a LATERAL JOINen algunos productos y versiones más nuevas del Estándar SQL). Como cualquier construcción lógica, no tiene un impacto directo en el rendimiento. En principio, deberíamos poder escribir una consulta usando cualquier sintaxis lógicamente equivalente, y el optimizador transformaría nuestra entrada en exactamente el mismo plan de ejecución física.

Por supuesto, esto requeriría que el optimizador conozca cada transformación posible y tenga tiempo para considerar cada una. Este proceso podría llevar más tiempo que la era actual del universo, por lo que la mayoría de los productos comerciales no adoptan este enfoque. Por lo tanto, la sintaxis de consultas puede, y a menudo lo hace, tener un impacto en el rendimiento final, aunque es difícil hacer declaraciones generales sobre cuál es mejor y por qué.

OUTER APPLY ( SELECT TOP ... )Es muy probable que la forma específica de resulte en una unión de bucles anidados correlacionados en las versiones actuales de SQL Server, porque el optimizador no contiene lógica para transformar este patrón en un equivalente JOIN. La unión de bucles anidados correlacionados puede no funcionar bien si la entrada externa es grande y la entrada interna no está indexada, o si las páginas necesarias aún no están en la memoria. Además, los elementos específicos del modelo de costos del optimizador significan que una unión de bucles anidados correlacionados es menos probable que una semánticamente idéntica JOINpara producir un plan de ejecución paralelo.

Pude hacer la misma consulta con una sola combinación izquierda y row_number ()

Esto puede o no ser mejor en el caso general. Deberá probar el rendimiento de ambas alternativas con datos representativos. El LEFT JOINy ROW_NUMBERsin duda tiene potencial de ser más eficiente, pero depende de la forma del plan de consulta precisa elegida. Los factores principales que afectan la eficiencia de este enfoque son la disponibilidad de un índice para cubrir las columnas necesarias y para suministrar el orden que necesitan las cláusulas PARTITION BYy ORDER BY. Un segundo factor es el tamaño de la tabla. Un índice eficiente y bien indexado APPLYpuede superar ROW_NUMBERa un índice óptimo si la consulta toca una porción relativamente pequeña de la tabla en cuestión. Se necesitan pruebas.

Paul White dice GoFundMonica
fuente
2

La primera consulta puede ejecutarse en paralelo con solo una solicitud al servidor sql. Obtuvo el registro completo y proporciona resultados basados ​​en criterios de filtro.

Pero en el caso de la segunda, se ejecuta fila por fila y, para cada fila, se escaneará Table2 y se agregará al resultado.

si su consulta externa tiene menos registro, la segunda es mejor (APLICACIÓN EXTERNA). Pero si la primera consulta puede obtener más datos, entonces debe usar la primera.

usuario55424
fuente