Quand devrais-je utiliser CROSS APPLY plutôt que INNER JOIN ?

Quand devrais-je utiliser CROSS APPLY plutôt que INNER JOIN ?


Source : Stack Overflow [sql-server]

Quelqu’un peut-il me donner un bon exemple de cas où CROSS APPLY fait une différence dans les cas où INNER JOIN fonctionnerait aussi ?

Consultez l’article sur mon blog pour une comparaison détaillée des performances :

CROSS APPLY fonctionne mieux sur les éléments qui n’ont pas de condition de JOIN simple.

Celui-ci sélectionne les 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

Cela ne peut pas être facilement formulé avec une condition INNER JOIN.

Vous pourriez probablement faire quelque chose comme cela en utilisant des CTE et des fonctions de fenêtrage :

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 :

Vérification effectuée.

master est une table d’environ 20 000 000 enregistrements 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

s’exécute pendant presque 30 secondes, tandis que celle-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ée.