Estou usando o SQL SERVER 2008 R2
Acabei de encontrar o APPLY no SQL e adorei como ele resolve problemas de consulta para tantos casos,
Muitas das tabelas que eu estava usando 2 left join para obter o resultado, consegui entrar em 1 outer apply.
Eu tenho uma pequena quantidade de dados em minhas tabelas de banco de dados locais e, após a implantação, o código deve ser executado em dados pelo menos 20 vezes grandes.
Estou preocupado que a aplicação externa possa demorar mais do que as 2 condições de junção esquerda para grande quantidade de dados,
Alguém pode dizer como exatamente o apply funciona e como isso afetará o desempenho em dados muito grandes, se possível algumas relações proporcionais com o tamanho de cada tabela como proporcional a n1^1 ou n1^2 ... onde n1 é o número de linhas na tabela 1.
Aqui está a consulta com 2 joins à esquerda
select EC.*,DPD.* from Table1 eC left join
(
select member_id,parent_gid,child_gid,LOB,group_gid,MAX(table2_sid) mdsid from Table2
group by member_id,parent_gid,child_gid,LOB,group_gid
) DPD2 on DPD2.parent_gid = Ec.parent_gid
AND DPD2.child_gid = EC.child_gid
AND DPD2.member_id = EC.member_id
AND DPD2.LOB = EC.default_lob
AND DPD2.group_gid = EC.group_gid
left join
Table2 dpd on dpd.parent_gid = dpd2.parent_gid
and dpd.child_gid = dpd2.child_gid
and dpd.member_id = dpd2.member_id
and dpd.group_gid = dpd2.group_gid
and dpd.LOB = dpd2.LOB
and dpd.table2_sid = dpd2.mdsid
Aqui está a consulta com aplicação externa
select * from Table1 ec
OUTER APPLY (
select top 1 grace_begin_date,retroactive_begin_date,Isretroactive
from Table2 DPD
where DPD.parent_gid = Ec.parent_gid
AND DPD.child_gid = EC.child_gid
AND DPD.member_id = EC.member_id
AND DPD.LOB = EC.default_lob
AND DPD.group_gid = EC.group_gid
order by DPD.table2_sid desc
) DPD
APPLY
é uma junção correlacionada (chamada deLATERAL JOIN
em alguns produtos e versões mais recentes do SQL Standard). Como qualquer construção lógica, não tem impacto direto no desempenho. Em princípio, devemos ser capazes de escrever uma consulta usando qualquer sintaxe logicamente equivalente, e o otimizador transformaria nossa entrada exatamente no mesmo plano de execução física.Obviamente, isso exigiria que o otimizador conhecesse todas as transformações possíveis e tivesse tempo para considerar cada uma delas. Esse processo pode demorar mais do que a idade atual do universo, então a maioria dos produtos comerciais não adota essa abordagem. Portanto, a sintaxe de consulta pode, e geralmente tem, um impacto no desempenho final, embora seja difícil fazer declarações gerais sobre o que é melhor e por quê.
A forma específica de
OUTER APPLY ( SELECT TOP ... )
provavelmente resultará em uma junção de loops aninhados correlacionados nas versões atuais do SQL Server, porque o otimizador não contém lógica para transformar esse padrão em umJOIN
. A junção de loops aninhados correlacionados pode não funcionar bem se a entrada externa for grande e a entrada interna não for indexada ou as páginas necessárias ainda não estiverem na memória. Além disso, elementos específicos do modelo de custo do otimizador significam que uma junção de loops aninhados correlacionados é menos provável que uma semanticamente idênticaJOIN
para produzir um plano de execução paralela.Isso pode ou não ser melhor no caso geral. Você precisará testar o desempenho de ambas as alternativas com dados representativos. O
LEFT JOIN
eROW_NUMBER
certamente tem potencial para ser mais eficiente, mas depende do formato preciso do plano de consulta escolhido. Os principais fatores que afetam a eficiência dessa abordagem são a disponibilidade de um índice para cobrir as colunas necessárias e fornecer a ordem necessária pelas cláusulasPARTITION BY
e .ORDER BY
Um segundo fator é o tamanho da tabela. Um eficiente e bem indexadoAPPLY
pode superar umROW_NUMBER
com indexação ideal se a consulta tocar uma parte relativamente pequena da tabela em questão. O teste é necessário.A primeira consulta pode ser executada em paralelo por apenas uma solicitação ao servidor sql. Ele buscou todo o registro e fornece saída com base nos critérios de filtro.
Mas, no caso do segundo, ele executa linha por linha e, para cada linha, a Tabela2 será verificada e anexada ao resultado.
se sua consulta externa tiver menos registro, a segunda será melhor (OUTER APPLY). Mas se a primeira consulta puder obter mais dados, você deve usar a primeira.