sql >> Base de Datos >  >> RDS >> Sqlserver

¿Cuándo debo usar CROSS APPLY sobre INNER JOIN?

¿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 JOIN vs. 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.