Qual é o principal objetivo do uso do CROSS APPLY ?
Li (vagamente, através de postagens na Internet) que cross apply
podem ser mais eficientes ao selecionar conjuntos de dados grandes, se você estiver particionando. (Paginação vem à mente)
Eu também sei que CROSS APPLY
não requer uma UDF como a tabela correta.
Na maioria das INNER JOIN
consultas (relacionamentos um para muitos), eu poderia reescrevê-las para uso CROSS APPLY
, mas elas sempre me oferecem planos de execução equivalentes.
Alguém pode me dar um bom exemplo de quando CROSS APPLY
faz a diferença nos casos em que INNER JOIN
também funcionará?
Editar:
Aqui está um exemplo trivial, onde os planos de execução são exatamente os mesmos. (Mostre-me onde eles diferem e onde cross apply
é mais rápido / mais 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
fonte
CROSS APPLY
tem seu uso óbvio em permitir que um conjunto dependa de outro (diferente doJOIN
operador), mas isso não tem um custo: ele se comporta como uma função que opera sobre cada membro do conjunto esquerdo ; portanto, nos termos do SQL Server, sempre execute aLoop Join
, que quase nunca é a melhor maneira de juntar conjuntos. Portanto, useAPPLY
quando precisar, mas não use demaisJOIN
.Respostas:
Veja o artigo no meu blog para uma comparação detalhada de desempenho:
INNER JOIN
vs.CROSS APPLY
CROSS APPLY
funciona melhor em coisas que não têm umaJOIN
condição simples .Este seleciona os
3
últimos registrost2
para cada registro entret1
:Não pode ser facilmente formulado com uma
INNER JOIN
condição.Você provavelmente poderia fazer algo assim usando
CTE
as funções de janela e:, mas isso é menos legível e provavelmente menos eficiente.
Atualizar:
Apenas verificado.
master
é uma tabela de20,000,000
registros com umPRIMARY KEY
onid
.Esta consulta:
é executado por quase
30
segundos, enquanto este:é instantâneo.
fonte
TVF
comINNER JOIN
?CROSS APPLY
, ele pediu quando escolherINNER JOIN
, quando isso também funcionaria.lateral join
no padrão (ANSI) SQLcross apply
às vezes permite que você faça coisas com as quais não pode fazerinner join
.Exemplo (um erro de sintaxe):
Este é um erro de sintaxe , porque, quando usadas com
inner join
, funções de tabela podem aceitar apenas variáveis ou constantes como parâmetros. (Ou seja, o parâmetro da função de tabela não pode depender da coluna de outra tabela.)Contudo:
Isso é legal.
Editar: ou, alternativamente, sintaxe mais curta: (por ErikE)
Editar:
Nota: O Informix 12.10 xC2 + possui tabelas derivadas laterais e o Postgresql (9.3+) possui subconsultas laterais que podem ser usadas para um efeito semelhante.
fonte
SELECT
necessário dentro doCROSS APPLY
. Por favor tenteCROSS APPLY dbo.myTableFun(O.name) F
.Considere que você tem duas tabelas.
TABELA MESTRE
TABELA DE DETALHES
Há muitas situações em que precisamos de substituir
INNER JOIN
comCROSS APPLY
.1. Junte duas tabelas com base nos
TOP n
resultadosConsidere se precisamos selecionar
Id
eName
deMaster
e últimas duas datas para cadaId
partirDetails table
.A consulta acima gera o seguinte resultado.
Veja, ele gerou resultados para as duas últimas datas e as duas últimas
Id
e uniu esses registros apenas na consulta externa ativadaId
, o que está errado. Isso deve retornarIds
1 e 2, mas retornou apenas 1 porque 1 tem as duas últimas datas. Para conseguir isso, precisamos usarCROSS APPLY
.e forma o seguinte resultado.
Aqui está como isso funciona. A consulta interna
CROSS APPLY
pode fazer referência à tabela externa, ondeINNER JOIN
não pode fazer isso (gera erro de compilação). Ao encontrar as duas últimas datas, a união é feita dentroCROSS APPLY
, ou sejaWHERE M.ID=D.ID
,.2. Quando precisamos de
INNER JOIN
funcionalidade usando funções.CROSS APPLY
pode ser usado como um substitutoINNER JOIN
quando precisamos obter resultados daMaster
tabela e afunction
.E aqui está a função
que gerou o seguinte resultado
VANTAGEM ADICIONAL DE APLICAÇÃO TRANSVERSAL
APPLY
pode ser usado como um substituto paraUNPIVOT
. De qualquerCROSS APPLY
ouOUTER APPLY
podem ser usados aqui, que são intercambiáveis.Considere que você tem a tabela abaixo (nomeada
MYTABLE
).A consulta está abaixo.
que traz o resultado
fonte
Parece-me que o CROSS APPLY pode preencher uma certa lacuna ao trabalhar com campos calculados em consultas complexas / aninhadas e torná-los mais simples e legíveis.
Exemplo simples: você tem um DoB e deseja apresentar vários campos relacionados à idade que também dependerão de outras fontes de dados (como emprego), como Age, AgeGroup, AgeAtHiring, MinimumRetirementDate etc. para uso em seu aplicativo de usuário final (Tabelas dinâmicas do Excel, por exemplo).
As opções são limitadas e raramente elegantes:
As subconsultas JOIN não podem introduzir novos valores no conjunto de dados com base nos dados da consulta pai (ele deve permanecer por si próprio).
UDFs são legais, mas lentos, pois tendem a impedir operações paralelas. E ser uma entidade separada pode ser uma coisa boa (menos código) ou ruim (onde está o código).
Tabelas de junção. Às vezes, eles podem funcionar, mas em breve você estará juntando subconsultas a toneladas de UNIÕES. Grande bagunça.
Crie ainda outra visão de uso único, supondo que seus cálculos não exijam dados obtidos no meio da consulta principal.
Tabelas intermediárias. Sim ... isso geralmente funciona, e muitas vezes é uma boa opção, pois eles podem ser indexados e rápidos, mas o desempenho também pode diminuir devido ao fato das instruções UPDATE não serem paralelas e não permitirem que as fórmulas em cascata (resultados de reutilização) atualizem vários campos no campo mesma declaração. E, às vezes, você prefere fazer as coisas de uma só vez.
Aninhando consultas. Sim, a qualquer momento, você pode colocar parênteses em toda a consulta e usá-la como uma subconsulta na qual é possível manipular os dados de origem e os campos calculados. Mas você só pode fazer isso muito antes que fique feio. Muito feio.
Repetindo código. Qual é o maior valor de três instruções longas (CASE ... ELSE ... END)? Isso será legível!
Perdi alguma coisa? Provavelmente, fique à vontade para comentar. Mas, ei, CROSS APPLY é como uma dádiva de Deus em tais situações: basta adicionar um simples
CROSS APPLY (select tbl.value + 1 as someFormula) as crossTbl
e pronto! Seu novo campo agora está pronto para uso praticamente como sempre existiu nos dados de origem.Os valores introduzidos através do CROSS APPLY ...
CROSS APPLY (select crossTbl.someFormula + 1 as someMoreFormula) as crossTbl2
Dang, não há nada que eles não possam fazer!
fonte
A aplicação cruzada também funciona bem com um campo XML. Se você deseja selecionar valores de nó em combinação com outros campos.
Por exemplo, se você tiver uma tabela contendo alguns xml
Usando a consulta
Retornará um resultado
fonte
Isso já foi respondido muito bem tecnicamente, mas deixe-me dar um exemplo concreto de como é extremamente útil:
Digamos que você tenha duas tabelas, Cliente e Pedido. Os clientes têm muitos pedidos.
Quero criar uma exibição que me forneça detalhes sobre os clientes e o pedido mais recente que eles fizeram. Com apenas JOINS, isso exigiria algumas auto-junções e agregação, o que não é bonito. Mas com o Cross Apply, é super fácil:
fonte
A aplicação cruzada pode ser usada para substituir a subconsulta onde você precisa de uma coluna da subconsulta
subconsulta
aqui não poderei selecionar as colunas da tabela da empresa, usando cross apply
fonte
Eu acho que deve ser legibilidade;)
O CROSS APPLY será um pouco exclusivo para as pessoas que estão lendo, dizendo que está sendo usado um UDF que será aplicado a cada linha da tabela à esquerda.
Claro, existem outras limitações em que um CROSS APPLY é melhor usado do que JOIN, que outros amigos postaram acima.
fonte
Aqui está um artigo que explica tudo, com sua diferença de desempenho e uso em JOINS.
SQL Server CROSS APPLY e OUTTER APPLY sobre JOINS
Conforme sugerido neste artigo, não há diferença de desempenho entre eles para operações normais de junção (INNER AND CROSS).
A diferença de uso chega quando você precisa fazer uma consulta como esta:
Ou seja, quando você precisa se relacionar com a função. Isso não pode ser feito usando INNER JOIN, o que causaria o erro "Não foi possível vincular o identificador de várias partes" D.DepartmentID "." Aqui, o valor é passado para a função à medida que cada linha é lida. Parece legal para mim. :)
fonte
Bem, não tenho certeza se isso se qualifica como um motivo para usar o Cross Apply versus Inner Join, mas essa consulta foi respondida em uma postagem do fórum usando o Cross Apply, portanto, não tenho certeza se existe um método equivalente usando o Inner Join:
COMO INICIAR
FIM
fonte
A essência do operador APPLY é permitir a correlação entre os lados esquerdo e direito do operador na cláusula FROM.
Ao contrário de JOIN, a correlação entre entradas não é permitida.
Falando sobre correlação no operador APPLY, quero dizer, do lado direito, que podemos colocar:
Ambos podem retornar várias colunas e linhas.
fonte
Talvez essa seja uma pergunta antiga, mas eu ainda amo o poder do CROSS APPLY de simplificar o reuso da lógica e fornecer um mecanismo de "encadeamento" para resultados.
Forneci um SQL Fiddle abaixo, que mostra um exemplo simples de como você pode usar o CROSS APPLY para executar operações lógicas complexas em seu conjunto de dados sem que as coisas fiquem confusas. Não é difícil extrapolar daqui cálculos mais complexos.
http://sqlfiddle.com/#!3/23862/2
fonte
Enquanto a maioria das consultas que empregam CROSS APPLY pode ser reescrita usando um INNER JOIN, o CROSS APPLY pode gerar um melhor plano de execução e melhor desempenho, pois pode limitar o conjunto que está sendo associado ainda antes que a associação ocorra.
Roubado daqui
fonte