Por favor considere las 2 declaraciones siguientes en SQL Server:servidor SQL - OUTER APPLY frente Sub-consultas
Ésta está utilizando anidados sub-consultas:
WITH cte AS
(
SELECT TOP 100 PERCENT *
FROM Segments
ORDER BY InvoiceDetailID, SegmentID
)
SELECT *, ReturnDate =
(SELECT TOP 1 cte.DepartureInfo
FROM cte
WHERE seg.InvoiceDetailID = cte.InvoiceDetailID
AND cte.SegmentID > seg.SegmentID),
DepartureCityCode =
(SELECT TOP 1 cte.DepartureCityCode
FROM cte
WHERE seg.InvoiceDetailID = cte.InvoiceDetailID
AND cte.SegmentID > seg.SegmentID)
FROM Segments seg
Y esto utiliza un OUTER APPLY operador:
WITH cte AS
(
SELECT TOP 100 PERCENT *
FROM Segments
ORDER BY InvoiceDetailID, SegmentID
)
SELECT seg.*, t.DepartureInfo AS ReturnDate, t.DepartureCityCode
FROM Segments seg OUTER APPLY (
SELECT TOP 1 cte.DepartureInfo, cte.DepartureCityCode
FROM cte
WHERE seg.InvoiceDetailID = cte.InvoiceDetailID
AND cte.SegmentID > seg.SegmentID
) t
¿Cuál de estos 2 potencialmente podría realizar mejor teniendo en cuenta que tanto la tabla de segmentos pueden tener potencialmente millones de filas?
Mi intuición es APLICACIÓN EXTERIOR funcionaría mejor.
Un par de preguntas más:
- Casi estoy bastante seguro de esto, pero todavía quería confirmar que en la primera solución, el CTE efectivamente sería ejecutado dos veces (debido a que su referencia a dos veces y CTE es ampliado en línea como una macro).
- ¿Se podría ejecutar CTE una vez por cada fila cuando se utiliza en el operador APLICACIÓN EXTERNA? ¿También se ejecutará para cada fila cuando se usa en consultas anidadas en la primera declaración?
plazo, inspeccionar planes de consulta –
'TOP 100 PERCENT ... ORDER BY' está optimizado por cierto y no tiene ningún efecto. Estoy de acuerdo en que el segundo debería funcionar mejor. También puede ver 'ROW_NUMBER' y' PARTITION BY' para obtener el 'TOP 1' por grupo. –