Lembro que uma vez tive um índice ausente em uma tabela e uma consulta estava demorando muito. No plano de execução, vi que uma varredura de tabela e uma mesclagem foram feitas. As estatísticas de IO me mostraram que cada núcleo fez uma varredura de tabela, ou melhor, fiz 6 varreduras de tabela. Agora eu me pergunto se cada núcleo faz uma varredura completa ou cada núcleo faz aproximadamente 1/6 da varredura da tabela? Tenho certeza de que, se eu tivesse um índice adequado, obteria apenas uma busca ou seria dividido para cada núcleo.
Espero que entendam o que menciono aqui, infelizmente não posso fornecer nenhuma informação, pois a questão acabou de surgir e meu problema foi resolvido anos atrás.
Para ser franco com você, não tenho certeza do que você quer dizer com "uma fusão foi feita". Você está falando sobre uma junção de mesclagem? Talvez você queira dizer um operador de paralelismo? No mínimo, posso responder à pergunta sobre varreduras de tabelas paralelas.
Suponho que o que você quer dizer com isso é que você executou
SET STATISTICS IO ON
antes de executar sua consulta e parte da saída incluiu algo assim:O rótulo "contagem de varredura" é um pouco enganador. Você não deve concluir que, se
STATISTICS IO
relatadas 6 verificações, todas as linhas da tabela foram verificadas 6 vezes. Considerando o seguinte exemplo simples de consulta em uma tabela heap chamadaheap_table
:Para essa consulta
STATISTICS IO
, deve relatar uma contagem de varredura de 1, certo? Mas o SQL Server claramente não precisava ler todas as linhas da tabela. Observar a definição do rótulo de contagem de varredura também é útil:Portanto, se sua consulta fez uma varredura paralela, eu esperaria ver uma contagem de varredura de pelo menos 6, mas isso não implica necessariamente que todas as linhas da tabela foram lidas seis vezes. Como você pode saber como as linhas foram distribuídas entre os núcleos da CPU?
A maneira mais fácil é apenas olhar para um plano de execução real. Se você observar os detalhes de uma verificação paralela, o SQL Server mostrará quantas linhas foram processadas por cada thread da CPU. Abaixo está uma imagem do que você pode ver emprestado do artigo de Paul White Planos de Execução Paralela – Ramos e Threads :
Como você disse, encontrou essa consulta anos atrás, então esse método não o ajudará. Em vez disso, precisamos examinar as técnicas disponíveis para o SQL Server para processamento de planos paralelos. Craig Freedman tem uma série de postagens de blog sobre o assunto. Do artigo Parallel Scan :
Bem, aí está. Como eu disse anteriormente, você pode testar isso facilmente executando uma consulta com uma verificação paralela e verificando os detalhes do operador de verificação paralela no plano de execução real.
Para ver isso de outra maneira, tente pensar em um cenário em que seja benéfico para o SQL Server fazer uma verificação completa da tabela por núcleo.
Suponha que você tenha uma
UNION ALL
consulta que referencia sua tabela seis vezes. Em princípio, o SQL Server poderia fazer cada varredura de tabela com um núcleo de forma independente e combinar os resultados no final. No entanto, o SQL Server não fará isso porque não fará paralelismo de pipeline . Mesmo que pudesse, pessoalmente não consigo pensar em nenhuma vantagem em fazer isso aqui, além de evitar parte da sobrecarga associada ao paralelismo.Você poderia ler sobre o tipo de transmissão paralela de execução e se perguntar se nesse cenário o SQL Server poderia fazer seis verificações completas de uma tabela, uma com cada núcleo. Para o tipo de transmissão de troca, o SQL Server envia todas as linhas para todos os threads do consumidor. No entanto, isso pode ser feito com uma varredura serial na tabela seguida por um tipo de troca paralela Distribute Streams . Na verdade, isso é o que você vê no exemplo de hash join. Não consigo pensar em nenhum benefício em fazer essa varredura em paralelo, especialmente quando o tipo de transmissão é usado apenas para tabelas relativamente pequenas.
Um caso em que suponho que isso poderia acontecer é se você tivesse uma junção de loop aninhado paralelo com uma tabela externa que continha 6 linhas e com uma varredura de tabela no lado interno da junção. Nesse caso, acredito que as varreduras de tabela serão concluídas por encadeamentos seriais independentes, de modo que cada núcleo faça sua própria varredura de tabela. É claro que essa consulta provavelmente terá um desempenho muito ruim e não é algo a ser almejado, especialmente quando a tabela externa tem mais de seis linhas.