¿Cuál es el propósito principal de usar CROSS APPLY ?
He leído (vagamente, a través de publicaciones en Internet) que cross apply
puede ser más eficiente al seleccionar sobre conjuntos de datos grandes si está particionando. (La paginación viene a la mente)
También sé que CROSS APPLY
no requiere un UDF como la tabla correcta.
En la mayoría de las INNER JOIN
consultas (relaciones uno a muchos), podría reescribirlas para usarlas CROSS APPLY
, pero siempre me dan planes de ejecución equivalentes.
¿Alguien puede darme un buen ejemplo de cuándo CROSS APPLY
marca la diferencia en aquellos casos en INNER JOIN
que funcionará también?
Editar:
Aquí hay un ejemplo trivial, donde los planes de ejecución son exactamente los mismos. (Muéstrame uno donde difieren y donde cross apply
es más rápido / más eficiente)
create table Company (
companyId int identity(1,1)
, companyName varchar(100)
, zipcode varchar(10)
, constraint PK_Company primary key (companyId)
)
GO
create table Person (
personId int identity(1,1)
, personName varchar(100)
, companyId int
, constraint FK_Person_CompanyId foreign key (companyId) references dbo.Company(companyId)
, constraint PK_Person primary key (personId)
)
GO
insert Company
select 'ABC Company', '19808' union
select 'XYZ Company', '08534' union
select '123 Company', '10016'
insert Person
select 'Alan', 1 union
select 'Bobby', 1 union
select 'Chris', 1 union
select 'Xavier', 2 union
select 'Yoshi', 2 union
select 'Zambrano', 2 union
select 'Player 1', 3 union
select 'Player 2', 3 union
select 'Player 3', 3
/* using CROSS APPLY */
select *
from Person p
cross apply (
select *
from Company c
where p.companyid = c.companyId
) Czip
/* the equivalent query using INNER JOIN */
select *
from Person p
inner join Company c on p.companyid = c.companyId
fuente
CROSS APPLY
tiene su uso obvio al permitir que un conjunto dependa de otro (a diferencia delJOIN
operador), pero eso no tiene un costo: se comporta como una función que opera sobre cada miembro del conjunto izquierdo , por lo que, en términos de SQL Server, siempre realice unLoop Join
, que casi nunca es la mejor manera de unir conjuntos. Por lo tanto, úseloAPPLY
cuando lo necesite, pero no lo use en excesoJOIN
.Respuestas:
Vea el artículo en mi blog para una comparación detallada del rendimiento:
INNER JOIN
vs.CROSS APPLY
CROSS APPLY
funciona mejor en cosas que no tienen unaJOIN
condición simple .Éste selecciona los
3
últimos registros det2
cada registro det1
:No se puede formular fácilmente con una
INNER JOIN
condición.Probablemente podría hacer algo así usando la función
CTE
's y ventana:, pero esto es menos legible y probablemente menos eficiente.
Actualizar:
Acabo de revisarlo.
master
es una tabla de20,000,000
registros con unPRIMARY KEY
encendidoid
.Esta consulta:
corre por casi
30
segundos, mientras que este:es instantáneo
fuente
TVF
conINNER JOIN
?CROSS APPLY
, preguntó cuándo elegirlo yINNER JOIN
cuándo funcionaría también.lateral join
SQL estándar (ANSI)cross apply
a veces te permite hacer cosas con las que no puedes hacerinner join
.Ejemplo (un error de sintaxis):
Este es un error de sintaxis porque, cuando se usa con
inner join
, las funciones de tabla solo pueden tomar variables o constantes como parámetros. (Es decir, el parámetro de la función de tabla no puede depender de la columna de otra tabla).Sin embargo:
Esto es legal
Editar: O, alternativamente, sintaxis más corta: (por ErikE)
Editar:
Nota: Informix 12.10 xC2 + tiene tablas derivadas laterales y Postgresql (9.3+) tiene subconsultas laterales que se pueden usar con un efecto similar.
fuente
SELECT
necesario dentro delCROSS APPLY
. Por favor, intenteCROSS APPLY dbo.myTableFun(O.name) F
.Considera que tienes dos mesas.
MESA PRINCIPAL
TABLA DE DETALLES
Hay muchas situaciones en las que debemos reemplazar
INNER JOIN
conCROSS APPLY
.1. Unir dos tablas basadas en
TOP n
resultados.Considere si necesitamos seleccionar
Id
yName
desdeMaster
y las dos últimas fechas para cada unoId
deDetails table
.La consulta anterior genera el siguiente resultado.
Vea, generó resultados para las últimas dos fechas con las últimas dos fechas
Id
y luego unió estos registros solo en la consulta externaId
, lo cual es incorrecto. Esto debería devolver tantoIds
1 como 2, pero solo devolvió 1 porque 1 tiene las dos últimas fechas. Para lograr esto, necesitamos usarCROSS APPLY
.y forma el siguiente resultado.
Así es como funciona. La consulta interna
CROSS APPLY
puede hacer referencia a la tabla externa, dondeINNER JOIN
no puede hacer esto (arroja un error de compilación). Al encontrar las dos últimas fechas, la unión se realiza dentroCROSS APPLY
, es decir,WHERE M.ID=D.ID
.2. Cuando necesitamos
INNER JOIN
funcionalidad usando funciones.CROSS APPLY
se puede usar como un reemplazoINNER JOIN
cuando necesitamos obtener resultados de laMaster
tabla y afunction
.Y aquí está la función.
que generó el siguiente resultado
VENTAJA ADICIONAL DE APLICACIÓN CRUZADA
APPLY
se puede usar como reemplazo deUNPIVOT
. Ya seaCROSS APPLY
oOUTER APPLY
puede usarse aquí, que son intercambiables.Considere que tiene la siguiente tabla (nombrada
MYTABLE
).La consulta está abajo.
que te trae el resultado
fuente
Me parece que CROSS APPLY puede llenar un cierto vacío cuando se trabaja con campos calculados en consultas complejas / anidadas, y hacerlos más simples y legibles.
Ejemplo simple: tiene un DoB y desea presentar múltiples campos relacionados con la edad que también dependerán de otras fuentes de datos (como el empleo), como Age, AgeGroup, AgeAtHiring, MinimumRetirementDate, etc. para usar en su aplicación de usuario final (Tablas dinámicas de Excel, por ejemplo).
Las opciones son limitadas y rara vez elegantes:
Las subconsultas JOIN no pueden introducir nuevos valores en el conjunto de datos en función de los datos de la consulta principal (debe ser independiente).
Los UDF son limpios, pero lentos, ya que tienden a evitar operaciones paralelas. Y ser una entidad separada puede ser algo bueno (menos código) o malo (dónde está el código).
Mesas de unión. A veces pueden funcionar, pero pronto te unes a subconsultas con toneladas de UNION. Gran desorden.
Cree otra vista de un solo propósito, suponiendo que sus cálculos no requieren datos obtenidos a mitad de su consulta principal.
Mesas intermedias. Sí ... eso generalmente funciona, y a menudo es una buena opción, ya que pueden indexarse y ser rápidos, pero el rendimiento también puede disminuir debido a que las declaraciones de ACTUALIZACIÓN no son paralelas y no permiten que las fórmulas en cascada (reutilizar resultados) actualicen varios campos dentro del misma declaración Y a veces prefieres hacer las cosas de una sola vez.
Consultas de anidamiento. Sí, en cualquier momento puede poner paréntesis en toda su consulta y usarlo como una subconsulta sobre la cual puede manipular los datos de origen y los campos calculados por igual. Pero solo puedes hacer esto mucho antes de que se ponga feo. Muy feo.
Repetir código. ¿Cuál es el mayor valor de 3 declaraciones largas (CASE ... ELSE ... END)? ¡Eso será legible!
¿Me he perdido algo? Probablemente, así que siéntete libre de comentar. Pero bueno, CROSS APPLY es como un regalo del cielo en tales situaciones: solo agregas un simple
CROSS APPLY (select tbl.value + 1 as someFormula) as crossTbl
y listo! Su nuevo campo ahora está listo para usar prácticamente como siempre había estado allí en sus datos de origen.Los valores introducidos a través de CROSS APPLY pueden ...
CROSS APPLY (select crossTbl.someFormula + 1 as someMoreFormula) as crossTbl2
¡Dang, no hay nada que no puedan hacer!
fuente
La aplicación cruzada también funciona bien con un campo XML. Si desea seleccionar valores de nodo en combinación con otros campos.
Por ejemplo, si tiene una tabla que contiene algunos xml
Usando la consulta
Devolverá un resultado
fuente
Esto ya se ha respondido muy bien técnicamente, pero permítanme dar un ejemplo concreto de cómo es extremadamente útil:
Digamos que tiene dos tablas, Cliente y Pedido. Los clientes tienen muchos pedidos.
Quiero crear una vista que me brinde detalles sobre los clientes y el pedido más reciente que han realizado. Con solo JOINS, esto requeriría algunas autouniones y agregaciones que no son bonitas. Pero con Cross Apply, es súper fácil:
fuente
La aplicación cruzada se puede utilizar para reemplazar las subconsultas donde necesita una columna de la subconsulta
subconsulta
aquí no podré seleccionar las columnas de la tabla de la compañía, así que, usando la aplicación cruzada
fuente
Supongo que debería ser legibilidad;)
CROSS APPLY será algo único para las personas que leen y les digan que se está utilizando un UDF que se aplicará a cada fila de la tabla de la izquierda.
Por supuesto, hay otras limitaciones en las que una APLICACIÓN CRUZADA se usa mejor que ÚNETE que otros amigos han publicado anteriormente.
fuente
Aquí hay un artículo que lo explica todo, con su diferencia de rendimiento y uso sobre JOINS.
SQL Server CROSS APPLY y OUTER APPLY over JOINS
Como se sugiere en este artículo, no hay diferencia de rendimiento entre ellos para las operaciones de unión normales (INTERIOR Y CRUZ).
La diferencia de uso llega cuando tienes que hacer una consulta como esta:
Es decir, cuando tienes que relacionarte con la función. Esto no se puede hacer utilizando INNER JOIN, que le daría el error "El identificador de varias partes" D.DepartmentID "no se pudo vincular". Aquí el valor se pasa a la función a medida que se lee cada fila. A mí me parece genial. :)
fuente
Bueno, no estoy seguro de si esto califica como una razón para usar Cross Apply versus Inner Join, pero esta consulta fue respondida por mí en una publicación del foro usando Cross Apply, por lo que no estoy seguro de si hay un método igual usando Inner Join:
COMO COMIENZA
FINAL
fuente
La esencia del operador APLICAR es permitir la correlación entre el lado izquierdo y derecho del operador en la cláusula FROM.
A diferencia de JOIN, la correlación entre entradas no está permitida.
Hablando de correlación en el operador APLICAR, quiero decir en el lado derecho podemos poner:
Ambos pueden devolver múltiples columnas y filas.
fuente
Esta es quizás una vieja pregunta, pero todavía me encanta el poder de CROSS APPLY para simplificar la reutilización de la lógica y proporcionar un mecanismo de "encadenamiento" para obtener resultados.
A continuación, proporcioné un Fiddle de SQL que muestra un ejemplo simple de cómo puede usar CROSS APPLY para realizar operaciones lógicas complejas en su conjunto de datos sin que las cosas se vuelvan desordenadas. No es difícil extrapolar desde aquí cálculos más complejos.
http://sqlfiddle.com/#!3/23862/2
fuente
Si bien la mayoría de las consultas que emplean CROSS APPLY pueden reescribirse usando INNER JOIN, CROSS APPLY puede generar un mejor plan de ejecución y un mejor rendimiento, ya que puede limitar el conjunto que se está uniendo antes de que se produzca la unión.
Robado de aquí
fuente