O paralelismo pode fazer com que as consultas tenham pior desempenho.

O paralelismo pode fazer com que as consultas tenham pior desempenho.


O paralelismo pode fazer com que as consultas tenham pior desempenho. 1Enquanto criava consultas de laboratório para o meu novo curso de Fundamentos da detecção de parâmetros – o primeiro ao vivo é na semana que vem, ainda há tempo para entrar -, deparei-me com uma consulta com um comportamento terrivelmente agradável.

Sempre fico arrasado quando construo os laboratórios práticos. Quero tornar os desafios fáceis o suficiente para que você possa realizá-los no espaço de uma hora, mas difíceis o suficiente para que eles … bem, desafio você.

É complicado andar nessa linha.

Essa consulta, no entanto … essa consulta, mesmo que seja apenas uma tabela com um índice não clusterizado, ultrapassa a linha que você provavelmente faria em uma classe de fundamentos. É tão diabólico que eu tenho que compartilhá-lo em algum lugar, então aqui estamos, caro leitor.

Vamos consultar a tabela Postagens para encontrar novas perguntas e respostas.

Estou usando a versão de 50 GB de 2013 do banco de dados Stack Overflow – grande o suficiente para receber um pouco de carne, mas pequena o suficiente para que você possa baixá-lo rapidamente para acompanhar (são apenas 10 GB compactados).

Todos os dias, durante todo o dia, as pessoas estão fazendo perguntas e postando respostas no StackOverflow.com. À medida que novas perguntas e respostas são publicadas, elas começam com CreationDate = agora e Score = 0.

Digamos que nossos usuários desejem encontrar postagens com uma quantidade mínima de pontos, respostas e comentários, e escrevemos este procedimento armazenado para ajudá-los:

Leia Também  Aprenda SQL: Visualizações SQL

Às vezes, nossos usuários desejam capturar novas perguntas antes que outras pessoas entrem. Esses usuários chamam isso de muito baixo ScoreMin, AnswerCountMin e CommentCountMin. Outros usuários estão procurando uma tabela de classificação – eles só querem ver as perguntas de classificação mais alta para poderem ler e aprender. Esses usuários chamam de HIGH ScoreMin, AnswerCountMin e CommentCountMin.

Com isso em mente, aqui estão os dois conjuntos de parâmetros com os quais testamos:

Damos uma chance àqueles e temos sorte – nossa consulta é executada rapidamente. Acontece que há um índice que nossa consulta usará, por isso estamos satisfeitos com esses planos reais, pois as duas consultas combinadas são executadas em apenas alguns segundos:

O paralelismo pode fazer com que as consultas tenham pior desempenho. 2

Demos uma rápida olhada, e ela está usando nosso índice, e os números reais são bem pequenos – somos bons aqui, certo? Enviá-lo.

Os leitores de olhos de águia observam que essa consulta faz uma varredura de índice, mas – isso não é necessariamente uma coisa ruim! Nesse caso, é bastante apropriado. O SQL Server fareja os parâmetros da primeira consulta (@ScoreMin = 1) e diz: “Será realmente fácil encontrar linhas com números tão baixos de pontuação, comentários e respostas. Eu poderia apenas digitalizar as postagens da CreationDate mais recente e fazer pesquisas importantes para cada uma delas. Não precisarei procurar muitas linhas antes de encontrar linhas suficientes com os mínimos certos para CommentCount e AnswerCount! ” E ele está certo. Caso você esteja acompanhando em casa, aqui está a definição para esse índice nas Postagens:

Mas tente executá-los na ordem oposta,
e o paralelismo torna as coisas terríveis.

Libere esse plano do cache e execute-o na ordem oposta:

E, ah – isso não é bom – a primeira consulta é rápida, mas a segunda consulta leva quase um minuto. O segredo está no molho, e por molho quero dizer planos de execução reais:

O paralelismo pode fazer com que as consultas tenham pior desempenho. 3

Vamos ver o que aconteceu quando a primeira chamada de proc foi executada:

  • Dessa vez, o SQL Server otimizou o plano do processo procurando Postagens com pontuação> = 250, AnswerCount> = 10 e CommentCount> = 10
  • Ele sabe que há MUITO menos publicações que correspondem a esses predicados
  • Ele ainda não queria fazer uma varredura de tabela – ainda queria usar o delicioso índice CreationDate porque satisfaz o ORDER BY
  • Mas sabia que teria que ler um muito de linhas desse índice para encontrar as correspondentes
  • Por isso, decidiu paralelizar a varredura no índice CreationDate_Score, permitindo que vários encadeamentos trabalhassem simultaneamente ao realizar todas essas pesquisas principais
  • Mas, por causa disso, quando o índice CreationDate é subitamente espalhado por vários segmentos de trabalho, a saída dos threads não é mais classificada pelo índice e precisa ser re-classificada novamente

Isso funciona bem para esses parâmetros, porque há relativamente poucas linhas com Pontuação> = 250, AnswerCount> = 10 e CommentCount> = 10. Não é difícil classificar essas linhas. Pedaço de bolo, a consulta é feita em menos de um segundo. Este é um uso completamente apropriado para paralelismo.

No entanto, vamos ver o que acontece quando a segunda chamada de proc é executada:

  • Estamos reutilizando o plano criado para Pontuação> = 250, Número de respostas> = 10 e Número de comentários> = 10
  • Mas há muito mais linhas com Pontuação> = 1, AnswerCount> = 0 e CommentCount> 0 – milhões, na verdade
  • Originalmente, quando usamos apenas 1 núcleo da CPU, podíamos fazer a varredura do índice para trás em um thread e parar de fazer pesquisas de chave assim que encontrássemos linhas suficientes para corresponder ao TOP 1000 em nossa consulta
  • Mas agora, como o trabalho foi paralelo, todos os threads precisam verificar todas as linhas no índice, fazendo pesquisas de chave para eles
  • E é claro que a má classificação também está ferrada, porque ele não alocou memória suficiente para classificar todas essas linhas

E bam, estamos em um mundo de mágoa.

Então, qual é a solução?

Há muitas opções diferentes aqui: ajuste de consulta, ajuste de índice, dicas, guias de plano, o nome dele – mas eu vou usar um que você provavelmente não esperaria apenas para mostrar que funciona. Vou colocar uma dica de OPTION (MAXDOP 1) na consulta:

O paralelismo pode fazer com que as consultas tenham pior desempenho. 4Com essa mudança em vigor, não há diferenças entre os planos, independentemente dos parâmetros inseridos primeiro. Ambas as consultas têm o primeiro plano discutido e são executadas em um segundo ou menos. Uma mudança semelhante envolveria definir o Limite de custo e o MAXDOP adequadamente para reduzir o raio da explosão, mas é claro que isso afetaria muito mais consultas.

Um sinal de paralelismo é a solução certa? Bem, há um buffet completo de opções para você escolher. Caramba, alguém poderia passar um dia inteiro apenas discutindo a questão fundamental em questão, ou até três dias dominando-a. O que me lembra – esta demonstração é muito difícil para a classe de fundamentos, mas se eu adicionar outro índice e usar um terceiro conjunto de parâmetros, introduzindo três combinações exclusivas de plano de consulta – sim, isso é perfeitamente diabólico para um laboratório de nível de Masterização. Vejo você na aula!

cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br