AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 174249
Accepted
John Eisbrener
John Eisbrener
Asked: 2017-05-23 12:17:07 +0800 CST2017-05-23 12:17:07 +0800 CST 2017-05-23 12:17:07 +0800 CST

Por que o operador de paralelismo (fluxos de partição) reduziria as estimativas de linha para 1?

  • 772

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:

insira a descrição da imagem aqui

Incluindo a Plan Tree no caso de adicionar mais contexto:

insira a descrição da imagem aqui

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.

sql-server sql-server-2012
  • 3 3 respostas
  • 8962 Views

3 respostas

  • Voted
  1. Best Answer
    Joe Obbish
    2017-05-23T16:57:55+08:002017-05-23T16:57:55+08:00

    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):

    O operador Repartição Streams consome vários fluxos e produz vários fluxos de registros. O conteúdo e o formato do registro não são alterados. Se o otimizador de consulta usar um filtro de bitmap, o número de linhas no fluxo de saída será reduzido.

    Além disso, um artigo sobre filtros de bitmap também é útil:

    Ao analisar um plano de execução contendo filtragem de bitmap, é importante entender como os dados fluem pelo plano e onde a filtragem é aplicada. O filtro de bitmap e bitmap otimizado são criados no lado da entrada de construção (tabela de dimensão) de uma junção de hash; no entanto, a filtragem real normalmente é feita no operador Parallelism, que está no lado de entrada do probe (a tabela de fatos) da junção de hash. No entanto, quando o filtro de bitmap é baseado em uma coluna inteira, o filtro pode ser aplicado diretamente à tabela inicial ou operação de varredura de índice em vez do operador Paralelismo. Essa técnica é chamada de otimização em linha.

    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_ROWem relação à tabela de fatos. Preparação de dados:

    create table outer_tbl (ID BIGINT NOT NULL);
    
    INSERT INTO outer_tbl WITH (TABLOCK)
    SELECT TOP (1000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
    FROM master..spt_values;
    
    create table inner_tbl_1 (ID BIGINT NULL);
    create table inner_tbl_2 (ID BIGINT NULL);
    
    INSERT INTO inner_tbl_1 WITH (TABLOCK)
    SELECT (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) / 2000000 - 2) NUM
    FROM master..spt_values t1
    CROSS JOIN master..spt_values t2;
    
    INSERT INTO inner_tbl_2 WITH (TABLOCK)
    SELECT (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) / 2000000 - 2) NUM
    FROM master..spt_values t1
    CROSS JOIN master..spt_values t2;
    

    Aqui está uma consulta que você não deve executar:

    SELECT *
    FROM outer_tbl o
    INNER JOIN inner_tbl_1 i ON o.ID = i.ID
    INNER JOIN inner_tbl_2 i2 ON o.ID = i2.ID
    OPTION (HASH JOIN, QUERYTRACEON 9481, QUERYTRACEON 8649);
    

    Eu carreguei o plano . Dê uma olhada no operador perto de inner_tbl_2:

    repartição de linhas perdidas

    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:

    distribuição de linha

    Com base nisso, suspeito que você tenha muitos valores repetidos para a Object1.Column21coluna. Se as colunas repetidas não estiverem no histograma de estatísticas , o Object4.Column19SQL 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.Object10e Database1.Schema1.Object11em uma tabela temporária e ver se continua a obter junções de loop aninhadas. Você pode alterar essa junção para a LEFT OUTER JOINpara que o otimizador de consulta não reduza o número de linhas nessa etapa. Você pode adicionar uma MAXDOP 1dica à sua consulta para ver o que acontece. Você poderia usarTOPjunto 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.

    • 9
  2. Paul White
    2017-05-24T02:45:43+08:002017-05-24T02:45:43+08:00

    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:

    • Bitmap Magic (ou… como o SQL Server usa filtros de bitmap) por mim
    • Parallel Hash Join por Craig Freedman
    • Bitmaps de execução de consulta pela equipe de processamento de consulta do SQL Server
    • Interpretando planos de execução contendo filtros de bitmap nos manuais online
    • Noções básicas sobre junções de hash nos livros on-line
    • 6
  3. SQLBek
    2017-05-23T13:48:26+08:002017-05-23T13:48:26+08:00

    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.

    • 0

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve