Alguém pode me dar um bom exemplo de quando o CROSS APPLY faz a diferença nos casos em que o INNER JOIN também funcionará?
Veja o artigo no meu blog para uma comparação detalhada de desempenho:
INNER JOIN
vs.CROSS APPLY
CROSS APPLY
funciona melhor em coisas que não têm um simples JOIN
doença. Este seleciona
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
Não pode ser formulado facilmente com um
INNER JOIN
doença. Você provavelmente poderia fazer algo assim usando
CTE
's e função de janela: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
, mas isso é menos legível e provavelmente menos eficiente.
Atualização:
Acabei de verificar.
master
é uma tabela de aproximadamente 20,000,000
registros com uma PRIMARY KEY
em 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
roda por quase
30
segundos, enquanto 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
é instantâneo.