Estou usando o SQL Server 2012 Enterprise. Eu me deparei com um SQL Plan que está exibindo algum comportamento que não acho totalmente intuitivo. Após uma operação pesada de Parallel Index Scan, ocorre uma operação de Parallelism (Repartition Streams), mas está matando as estimativas de linha retornadas pelo Index Scan (Object10.Index2), reduzindo a estimativa para 1. Fiz algumas pesquisas, mas não encontrei nada que explique esse comportamento. A consulta é bastante simples, embora cada uma das tabelas contenha registros na casa dos milhões. Isso faz parte de um processo de carregamento DWH e esse conjunto de dados intermediário é tocado algumas vezes, mas a pergunta que tenho está relacionada às estimativas de linha em particular. Alguém pode explicar por que as estimativas de linha precisas vão para 1 dentro do operador de Paralelismo (Strems de Partição)? Também,
Eu postei o plano completo para Colar o Plano .
Aqui está a operação em questão:
Incluindo a Plan Tree no caso de adicionar mais contexto:
Eu poderia estar encontrando alguma variação deste item do Connect arquivado por Paul White (explicação mais detalhada em seu blog aqui )? Pelo menos é a única coisa que encontrei que parece estar remotamente perto do que estou encontrando, embora não haja um operador TOP em jogo.
Os planos de consulta com filtros de bitmap às vezes podem ser difíceis de ler. Do artigo BOL para fluxos de repartição (ênfase minha):
Além disso, um artigo sobre filtros de bitmap também é útil:
Eu acredito que é isso que você está observando com sua consulta. É possível criar uma demonstração relativamente simples para mostrar um operador de repartição de fluxos reduzindo uma estimativa de cardinalidade, mesmo quando o operador de bitmap está
IN_ROW
em relação à tabela de fatos. Preparação de dados:Aqui está uma consulta que você não deve executar:
Eu carreguei o plano . Dê uma olhada no operador perto de
inner_tbl_2
:Você também pode achar útil o segundo teste em Hash Joins on Nullable Columns de Paul White.
Existem algumas inconsistências na forma como a redução de linha é aplicada. Só consegui ver em um plano com pelo menos três mesas. No entanto, a redução nas linhas esperadas parece razoável com a distribuição de dados correta. Suponha que a coluna unida na tabela de fatos tenha muitos valores repetidos que não estão presentes na tabela de dimensões. Um filtro de bitmap pode eliminar essas linhas antes que elas atinjam a junção. Para sua consulta, a estimativa é reduzida para 1. Como as linhas são distribuídas entre a função de hash fornece uma boa dica:
Com base nisso, suspeito que você tenha muitos valores repetidos para a
Object1.Column21
coluna. Se as colunas repetidas não estiverem no histograma de estatísticas , oObject4.Column19
SQL Server poderá obter a estimativa de cardinalidade muito errada.Eu acho que você deve se preocupar, pois pode ser possível melhorar o desempenho da consulta. Obviamente, se a consulta atender aos requisitos de tempo de resposta ou SLA, talvez não valha a pena investigar mais. No entanto, se você deseja investigar mais, há algumas coisas que você pode fazer (além de atualizar as estatísticas) para ter uma ideia se o otimizador de consulta escolheria um plano melhor se tivesse informações melhores. Você pode colocar os resultados da junção entre
Database1.Schema1.Object10
eDatabase1.Schema1.Object11
em uma tabela temporária e ver se continua a obter junções de loop aninhadas. Você pode alterar essa junção para aLEFT OUTER JOIN
para que o otimizador de consulta não reduza o número de linhas nessa etapa. Você pode adicionar umaMAXDOP 1
dica à sua consulta para ver o que acontece. Você poderia usarTOP
junto com uma tabela derivada para forçar a junção a ser a última, ou você pode até comentar a junção da consulta. Espero que essas sugestões sejam suficientes para você começar.Em relação ao item de conexão na pergunta, é extremamente improvável que esteja relacionado à sua pergunta. Esse problema não tem a ver com estimativas de linha ruins. Tem a ver com uma condição de corrida em paralelismo que faz com que muitas linhas sejam processadas no plano de consulta nos bastidores. Aqui parece que sua consulta não está fazendo nenhum trabalho extra.
O problema central aqui é uma estimativa de cardinalidade ruim para o resultado da primeira junção. Isso pode surgir por vários motivos, mas na maioria das vezes são estatísticas desatualizadas ou vários predicados de junção correlacionados, que o modelo padrão do otimizador assume que são independentes.
No último caso, CORREÇÃO: desempenho ruim ao executar uma consulta que contém predicados AND correlacionados no SQL Server 2008 ou no SQL Server 2008 R2 ou no SQL Server 2012 pode ser relevante usando o sinalizador de rastreamento suportado 4137. Você também pode tentar a consulta com sinalizador de rastreamento 4199 para habilitar correções do otimizador e/ou 2301 para habilitar extensões de modelagem. É difícil saber com base em um plano anônimo.
A presença do bitmap não afeta diretamente a estimativa de cardinalidade da junção, mas torna seu efeito visível mais cedo aplicando a redução de semijunção antecipada. Sem o bitmap, a estimativa de cardinalidade para a primeira junção seria a mesma e o restante do plano ainda seria otimizado de acordo.
Se você estiver curioso, em um sistema de teste, você pode desabilitar bitmaps para a consulta com o sinalizador de rastreamento 7498. Você também pode desabilitar bitmaps otimizados (considerados pelo otimizador e afetando as estimativas de cardinalidade), substituindo-os por bitmaps pós-otimização (não considerados pelo otimizador, sem efeito na cardinalidade) com uma combinação dos sinalizadores de rastreamento 7497 e 7498. Nenhum deles é documentado ou suportado para uso em um sistema de produção, mas eles produzem planos que o otimizador poderia considerar normalmente e, portanto, podem ser forçados com um guia de planos.
Nada disso resolverá o problema central da estimativa ruim para a primeira junção, conforme observado acima, então estou apenas mencionando isso por interesse.
Leitura adicional sobre bitmaps e junções de hash:
respondeu a você no Twitter. Eu olhei para o XML anexado e vi paralelismo desequilibrado. 1 thread tem quase todas as linhas reais, enquanto a maioria dos outros não. Isso grita paralelismo desequilibrado que está ocorrendo. Portanto, eu examinaria o valor da chave/junção e suas respectivas estatísticas e cardinalidade.
De acordo com sua outra ideia, não tenho tanta certeza de que o item Connect se aplique, pois seu plano colado não contém TOP em nenhum lugar que eu vi.