Quelqu'un peut-il me donner un bon exemple de cas où CROSS APPLY fait une différence dans les cas où INNER JOIN fonctionnera également ?
Voir l'article de mon blog pour une comparaison détaillée des performances :
INNER JOIN
vsCROSS APPLY
CROSS APPLY
fonctionne mieux sur les choses qui n'ont pas de simple JOIN
état.
Celui-ci sélectionne 3
derniers enregistrements de t2
pour chaque enregistrement 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
Il ne peut pas être facilement formulé avec un INNER JOIN
état.
Vous pourriez probablement faire quelque chose comme ça en utilisant CTE
's et fonction de fenêtre :
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
, mais c'est moins lisible et probablement moins efficace.
Mise à jour :
Je viens de vérifier.
master
est une table d'environ 20,000,000
enregistre avec une PRIMARY KEY
sur id
.
Cette requête :
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
dure presque 30
secondes, tandis que celui-ci :
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
est instantané.