Tenho o seguinte código em uma instância gerenciada do SQL Server Azure e o desempenho é bem ruim.
INSERT INTO #CU WITH (TABLOCKX) (LA_ID, CU_ID)
SELECT la.LA_ID,
c2.CU_ID
FROM #la la
INNER JOIN dbo.T1 c ON c.CU_ID = la.CU_ID
INNER JOIN dbo.T1 c2 ON c2.Parent_CU_ID = c.Parent_CU_ID
WHERE c.Parent_CU_ID > 0
AND c.CU_ID <> c2.CU_ID
AND la.Flag1 = 1
AND EXISTS (SELECT 1 FROM #cid WHERE c2.CU_ID = ID)
Tenho um índice filtrado em T1.Flag, e se eu remover a desigualdade o desempenho é mais do que aceitável (5 minutos para 10 segundos), então estou confiante de que meu problema é com a desigualdade, mas não consigo pensar em nenhum padrão que me dará os mesmos resultados, mas terá um desempenho melhor. Alguma sugestão? Plano
#EquipeLegadoCE
Como o problema não é com a cardinalidade em nível de tabela, você pode querer forçar o uso do estimador de cardinalidade legado. Estar no Nível de Compatibilidade 150 usa uma estimativa de junção diferente , o que parece ser bastante incorreto.
Você pode fazer isso com esta dica:
É claro que há outros problemas que podem ser corrigidos com uma melhor estimativa de junção.
Baixo custo do plano: A estimativa de 16k linhas resulta em um custo estimado de ~3,4 Query Bucks, o que lhe dá um plano serial. Esse é um caminho ruim para escolher quando seus valores reais são 144.688.210 linhas e 61.962.838 linhas.
No Batch Mode: Batch Mode On Row Store seria uma escolha muito mais palatável junto com um plano paralelo ao juntar tantas linhas. Novamente, ele pode entrar em ação naturalmente com um plano estimado e orçado adequadamente, mas se não entrar, você precisará usar os truques usuais para que o otimizador o escolha.
deixando tudo isso de lado
Eu provavelmente gostaria de verificar duas vezes se essa consulta está escrita corretamente. Começar com contagens de linhas em meados de dez mil e produzir resultados unidos de 144 milhões e 62 milhões de linhas parece bem vulgar.
Além disso, mesmo corrigindo os itens acima, o tempo de execução da consulta será reduzido para cerca de 4 minutos (embora talvez seja menor se a inserção terminar em uma zona paralela, conforme pretendido pela
TABLOCK
dica).Isso provavelmente não pode ser corrigido, já que você está em um produto de nuvem da Microsoft condenável com discos feitos de asfalto quente. Inserir 62 milhões de linhas ali continuará sendo um ponto de travamento, e é por isso que perguntei se a consulta está escrita corretamente.
Se estiver escrito corretamente, você pode encontrar algum alívio adicionando um
DISTINCT
ouROW_NUMBER
na mistura. Muitas dessas linhas que estão sendo inseridas são provavelmente duplicatas desnecessárias que poderiam ser removidas do resultado final.