Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Wann sollte ich CROSS APPLY über INNER JOIN verwenden?

Kann mir jemand ein gutes Beispiel dafür geben, wann CROSS APPLY in den Fällen einen Unterschied macht, in denen INNER JOIN auch funktioniert?

Siehe den Artikel in meinem Blog für einen detaillierten Leistungsvergleich:

  • INNER JOIN vs. CROSS APPLY

CROSS APPLY funktioniert besser bei Dingen, die kein einfaches JOIN haben Zustand.

Dieser wählt 3 aus letzte Aufzeichnungen von t2 für jeden Datensatz von 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

Es lässt sich nicht einfach mit einem INNER JOIN formulieren Zustand.

Sie könnten so etwas wahrscheinlich mit CTE machen 's und Fensterfunktion:

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

, aber das ist weniger lesbar und wahrscheinlich weniger effizient.

Aktualisierung:

Gerade überprüft.

master ist eine Tabelle von etwa 20,000,000 Datensätze mit einem PRIMARY KEY auf id .

Diese Abfrage:

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

läuft für fast 30 Sekunden, während diese hier:

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

ist sofort.