¿Alguien puede darme un buen ejemplo de cuándo CROSS APPLY marca la diferencia en aquellos casos en los que INNER JOIN también funcionará?
Consulte el artículo de mi blog para obtener una comparación detallada del rendimiento:
INNER JOINvs.CROSS APPLY
CROSS APPLY funciona mejor en cosas que no tienen un simple JOIN condición.
Este selecciona 3 últimos registros de t2 para cada registro de t1 :
SELECT t1.*, t2o.*
FROM t1
CROSS APPLY
(
SELECT TOP 3 *
FROM t2
WHERE t2.t1_id = t1.id
ORDER BY
t2.rank DESC
) t2o
No se puede formular fácilmente con un INNER JOIN condición.
Probablemente podrías hacer algo así usando CTE 's y función de ventana:
WITH t2o AS
(
SELECT t2.*, ROW_NUMBER() OVER (PARTITION BY t1_id ORDER BY rank) AS rn
FROM t2
)
SELECT t1.*, t2o.*
FROM t1
INNER JOIN
t2o
ON t2o.t1_id = t1.id
AND t2o.rn <= 3
, pero esto es menos legible y probablemente menos eficiente.
Actualización:
Acabo de comprobar.
master es una tabla de alrededor de 20,000,000 registros con una PRIMARY KEY en id .
Esta consulta:
WITH q AS
(
SELECT *, ROW_NUMBER() OVER (ORDER BY id) AS rn
FROM master
),
t AS
(
SELECT 1 AS id
UNION ALL
SELECT 2
)
SELECT *
FROM t
JOIN q
ON q.rn <= t.id
dura casi 30 segundos, mientras que este:
WITH t AS
(
SELECT 1 AS id
UNION ALL
SELECT 2
)
SELECT *
FROM t
CROSS APPLY
(
SELECT TOP (t.id) m.*
FROM master m
ORDER BY
id
) q
es instantáneo.