Vou começar dizendo que não sou um DBA, apenas um dev que está tentando descobrir problemas de desempenho com a seguinte consulta que temos.
SELECT
OCCoverID as StaffID, FullName, SUM(OCWeight) AS Num
FROM vuOCStaffAbsentExpandedMini
INNER JOIN vuStaff ON OCCoverID = StaffID
WHERE
SADate = '2019-10-4'
AND MIDent = 506
AND SASupplyID IS NULL
AND CoverStaffSupplyID IS NULL
AND StaffMIDent <> 1
GROUP BY
OCCoverID, FullName
Demora cerca de 1 minuto para executar todas as vezes, verificamos duas vezes (achamos) todos os índices necessários, executamos o sintonizador de índice e ainda temos os mesmos problemas. Abaixo está o plano real que ele cria.
Qualquer ajuda seria apreciada, estamos usando o sql server 2012 express
Você tem um spool de desempenho que alimenta seu operador de loops aninhados (não aplicável)
...com estimativas muito baixas.
Agora, para cada valor na entrada superior (externa), o spool da tabela produzirá uma religação. Nenhum retrocesso é possível para spools de desempenho em junções de loop aninhado não aplicadas.
Fonte: Paul White sobre junções de loops aninhados e spool de desempenho
As baixas estimativas resultam na situação real abaixo:
Você pode validar a alta contagem de linhas da saída de spool multiplicando ambas as entradas (da escala de computação e do agregado de fluxo).
515 728
(entrada externa)* 168
(entrada interna) =86 642 304
Soluções
A primeira coisa a corrigir seria corrigir por que as estimativas são tão baixas.
Você pode tentar atualizar as estatísticas da tabela referenciada na exibição.
Mas parece que você está fazendo uma
LIKE
comparação entredbo.TblOnCall
e as tabelas que alimentam o operador de carretel.Isso também pode ser visto no operador NL que obtém os dados do spool.
(
EXPR 1137
= entrada externa,UNION
= entrada interna).Para uma solução de longo prazo ,
Eu corrigiria essa
LIKE
comparação e quaisquer outras partes que afetariam gravemente suas estimativas.Teríamos que ver as visualizações para fornecer as recomendações de consulta mais corretas.
Para uma correção rápida temporária , você pode desabilitar o spool com um sinalizador de rastreamento ou uma dica de consulta.
Um exemplo de implementação disso está executando
DBCC TRACEON(8690,-1)
(será removido na reinicialização da instância)Ou melhor, executando a consulta com
OPTION(QUERYTRACEON 8690)