¿Cuál es el propósito principal de usar CROSS APPLY ?
He leído (vagamente, a través de publicaciones en Internet) que cross applypuede 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 APPLYno requiere un UDF como la tabla correcta.
En la mayoría de las INNER JOINconsultas (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 APPLYmarca la diferencia en aquellos casos en INNER JOINque 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 applyes 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 APPLYtiene su uso obvio al permitir que un conjunto dependa de otro (a diferencia delJOINoperador), 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, úseloAPPLYcuando lo necesite, pero no lo use en excesoJOIN.Respuestas:
Vea el artículo en mi blog para una comparación detallada del rendimiento:
INNER JOINvs.CROSS APPLYCROSS APPLYfunciona mejor en cosas que no tienen unaJOINcondición simple .Éste selecciona los
3últimos registros det2cada registro det1:No se puede formular fácilmente con una
INNER JOINcondició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.
masteres una tabla de20,000,000registros con unPRIMARY KEYencendidoid.Esta consulta:
corre por casi
30segundos, mientras que este:es instantáneo
fuente
TVFconINNER JOIN?CROSS APPLY, preguntó cuándo elegirlo yINNER JOINcuándo funcionaría también.lateral joinSQL estándar (ANSI)cross applya 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
SELECTnecesario 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 JOINconCROSS APPLY.1. Unir dos tablas basadas en
TOP nresultados.Considere si necesitamos seleccionar
IdyNamedesdeMastery las dos últimas fechas para cada unoIddeDetails table.La consulta anterior genera el siguiente resultado.
Vea, generó resultados para las últimas dos fechas con las últimas dos fechas
Idy luego unió estos registros solo en la consulta externaId, lo cual es incorrecto. Esto debería devolver tantoIds1 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 APPLYpuede hacer referencia a la tabla externa, dondeINNER JOINno 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 JOINfuncionalidad usando funciones.CROSS APPLYse puede usar como un reemplazoINNER JOINcuando necesitamos obtener resultados de laMastertabla y afunction.Y aquí está la función.
que generó el siguiente resultado
VENTAJA ADICIONAL DE APLICACIÓN CRUZADA
APPLYse puede usar como reemplazo deUNPIVOT. Ya seaCROSS APPLYoOUTER APPLYpuede 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 crossTbly 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