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 / 73546
Accepted
crokusek
crokusek
Asked: 2014-08-09 12:51:49 +0800 CST2014-08-09 12:51:49 +0800 CST 2014-08-09 12:51:49 +0800 CST

Por que o CTE recursivo estima apenas 1 linha?

  • 772

Dados dois CTEs recursivos em cascata, autocontidos (sem tabelas reais):

create view NumberSequence_0_100_View
as
with NumberSequence as
(
    select 0 as Number
    union all
    select Number + 1
      from NumberSequence    
     where Number < 100
)
select Number
  from NumberSequence;
go

create view NumberSequence_0_10000_View
as
select top 10001
       v100.Number * 100 + v1.Number as Number
  from Common.NumberSequence_0_100_View v100
 cross join Common.NumberSequence_0_100_View v1
 where v1.Number < 100
   and v100.Number * 100 + v1.Number <= 10000
    -- please resist complaining about "order by in view" for this question
 order by v100.Number * 100 + v1.Number 
go

Em seguida, gere planos estimados/reais para:

select * from NumberSequence_0_10000_View

Estimativa insira a descrição da imagem aqui real CascadingCtePlan

Tempo de execução de 23 ms, mas estimando apenas uma linha para a saída final (2 linhas apenas para a primeira exibição).

O problema é que, quando isso é usado como uma subconsulta para unir dados reais (por "DaysAgo", por exemplo), o plano geralmente é um loop aninhado muito lento e geralmente preciso adicionar uma dica de junção/ordem reversa etc.

Existe alguma maneira de melhorar a estimativa, mantendo a abordagem CTE? Já houve uma solicitação de dica "with (AssumeMinRows = N)"? Isso parece ser um ótimo auxiliar de propósito geral para muitos casos (não apenas CTEs).

sql-server sql-server-2012
  • 1 1 respostas
  • 865 Views

1 respostas

  • Voted
  1. Best Answer
    Paul White
    2015-09-29T04:01:50+08:002015-09-29T04:01:50+08:00

    Por que o CTE recursivo estima apenas 1 linha?

    A estimativa de cardinalidade para expressões de tabela comuns recursivas é extremamente limitada.

    Sob o modelo original de estimativa de cardinalidade, a estimativa é uma soma simples das estimativas de cardinalidade para a âncora e as partes recursivas. Isso é equivalente a assumir que a parte recursiva é executada exatamente uma vez.

    No SQL Server 2014, com o novo modelo de estimativa de cardinalidade habilitado, a lógica é levemente alterada para assumir três execuções da parte recursiva, com o mesmo número de linhas retornadas a cada iteração.

    Ambos são suposições não educadas, então não é surpresa que o uso de CTes recursivos geralmente resulte em estimativas de baixa qualidade. De forma mais geral, estimar o resultado de um processo recursivo é quase impossível, então o otimizador nem tenta. Isso não é alterado pelo uso de uma estrutura recursiva particularmente simples, claramente destinada a produzir números sequenciais - o otimizador não tem lógica para detectar esse padrão.

    Em seu caso particular, a estimativa final é uma porque o otimizador faz mais suposições sobre a seletividade de predicados como [Recr1007]<(100)(no filtro no ID do nó 3) e ([Recr1003]*(100)+[Recr1007])<=(10000)(o predicado residual na junção de loops aninhados no ID do nó 2). Novamente, essas são suposições e os resultados são infelizes, embora não surpreendentes.

    Existe alguma maneira de melhorar a estimativa, mantendo a abordagem CTE?

    Não que eu saiba.

    Já houve uma solicitação de dica "with (AssumeMinRows = N)"?

    Não diretamente nesses termos. Tem havido muitos pedidos de materialização de um CTE , o que ajudaria se tal materialização viesse com geração automática de estatísticas. Não vou listar as outras porque parece que você já comentou a maioria dessas sugestões :)

    Também houve sugestões para dicas de seletividade , mas nada como isso chegou ao produto ainda.

    Conforme observado nos comentários sobre a pergunta, sua melhor aposta agora é usar uma tabela de números reais em vez de gerar uma dinamicamente usando um CTE recursivo. Uma segunda opção é usar a materialização manual - uma tabela temporária - como tenho certeza de que você sabe.

    • 7

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