Eu tenho uma consulta que estava executando lentamente anteriormente. Mais tarde descobri que não estava rodando em paralelo e isso está tornando a execução da consulta lenta.
A consulta envolve um grande view
e, em seguida, consulta a exibição com muitos temp tables
e sub query
.
Eu removi um UDF
da view e usei inline functions
e também usei um escalar TVF
e então ele começou a rodar rápido no parallel execution
.
Estava indo bem por alguns dias e um belo dia notei que a consulta rodava lentamente. Então verifiquei o plano de execução e descobri que a consulta está sendo executada no modo serial. Verifiquei o cache do plano para a consulta e vi muitos planos em cache envolvendo essa visualização. Excluí planos que não são paralelos e a consulta é executada rapidamente.
Agora eu faço isso todas as manhãs para forçar a consulta a ser executada em paralelo.
Detalhes adicionais:
- SQL Server 2016 Padrão
- A consulta é gerada via LINQ-SQL do aplicativo dot net. Portanto, consulta ad hoc.
Como posso forçar a consulta a ser executada em paralelo para sempre?
À primeira vista, isso soa como um problema clássico de sniffing de parâmetros .
O SQL Server cria um plano de execução para o primeiro conjunto de parâmetros que é chamado quando o plano precisa ser compilado e, em seguida, reutiliza esse plano várias vezes ao longo do dia. Você pode ver quais são os parâmetros - quando estiver visualizando o plano serial, clique com o botão direito do mouse na instrução select e vá para propriedades. Na janela de propriedades, procure Parâmetros e, em seguida, Valores Compilados. Isso mostrará quais valores produzem o plano serial.
Para forçar o plano a sempre ser executado em paralelo, você tem várias opções diferentes (muitas das quais Erland aborda em seu excelente post que vinculei acima), incluindo:
Essa é apenas uma resposta rápida - mas para muito, muito mais, leia a excelente postagem de Erland, Slow in the App, Fast in SSMS, que explica como uma consulta pode obter planos diferentes e como corrigi-la.
Pode ser difícil fornecer uma resposta precisa para seu problema, pois não sabemos como são suas consultas, mas você pode forçar um plano específico usando o recurso QueryStore que foi introduzido no SQL 2016. Se você estiver usando uma versão anterior do SQL Server ou não sente que o armazenamento de consultas é uma solução para você - você pode tentar coisas como:
Você também deve revisar postagens anteriores no StackExchange sobre este tópico, por exemplo, SQL não envolve paralelismo para consulta extremamente grande
Se o custo da consulta exceder o
Cost Threshold of Parallelism
valor ecost of the parallel plan
for menor quecost of a serial plan
, um plano paralelo será criado e usado.Em alguns casos, o QO escolhe o plano serial do que o plano paralelo porque
parallel plan
é mais caro do queserial plan
nesse caso. Por exemplo, se a consulta contém operadores escalares ou relacionais que não podem ser executados em modo paralelo.Em alguns casos, o QO toma decisões erradas devido a informações imprecisas, estatísticas desatualizadas,
cardinality estimate
etc. Devido ao qual o custo do plano serial é ligeiramente superior aparallel plan
.então QO ainda escolhe o plano serial.
Para superar esse problema, a consulta pode ser otimizada e as estatísticas também devem ser atualizadas.
Isso ajuda QO na tomada de decisão correta.
Essas são etapas bem-vindas, assim que você melhorar sua consulta, alguns dos planos foram paralelos e o desempenho da consulta melhorou.
Portanto, pode haver mais escopo para melhorar sua consulta.
Deve-se prestar mais atenção na otimização do índice de consulta e ajuste do que tentar imediatamente
Hint
O resto das coisas como usar HINT, sniffing de parâmetro, OPTION (RECOMPILE) já são discutidas.