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 / 249969
Accepted
Morris de Oryx
Morris de Oryx
Asked: 2019-10-01 16:04:06 +0800 CST2019-10-01 16:04:06 +0800 CST 2019-10-01 16:04:06 +0800 CST

Melhorando estimativas de valores distintos no Postgres

  • 772

Contagens completas no Postgres podem ser lentas, por razões que são bem compreendidas e muito discutidas. Então, eu tenho usado técnicas de estimativa em vez disso, sempre que possível. Para linhas, pg_stats parece bom, para visualizações, extrair uma estimativa retornada por EXPLAINfunciona bem.

https://www.cybertec-postgresql.com/en/count-made-fast/

Mas e os valores distintos? Aqui, tive muito menos sorte. Às vezes as estimativas estão 100% corretas, às vezes elas estão erradas por fatores de 2 ou 20. Tabelas truncadas parecem ter estimativas muito obsoletas em particular (?).

Acabei de fazer este teste e dei alguns resultados:

analyze assembly_prods; -- Doing an ANLYZE to give pg_stats every help.

select 'count(*) distinct' as method,
        count(*) as count
from (select distinct assembly_id 
      from assembly_prods) d 
union all
select 'n_distinct from pg_stats' as method,
        n_distinct as count
from pg_stats 
where tablename  = 'assembly_prods' and
      attname    = 'assembly_id';

Os resultados:

method                      count
count(*) distinct           28088
n_distinct from pg_stats    13805

Isso é apenas um fator de 2, mas eu pareço muito pior em meus dados. A ponto de não usar estimativas. Existe algo mais que eu possa tentar? Isso é algo que o PG 12 melhora?

Acompanhamento

Eu nunca tinha experimentado SET STATISTICSantes, porque há apenas tantas horas em um dia. Inspirado pela resposta de Laurenz, dei uma olhada rápida. Aqui está um comentário útil da documentação:

https://www.postgresql.org/docs/current/planner-stats.html

A quantidade de informações armazenadas pg_statisticpor ANALYZE, em particular o número máximo de entradas nas most_common_valsmatrizes e histogram_bounds para cada coluna, pode ser definida coluna por coluna usando o ALTER TABLE SET STATISTICScomando ou globalmente definindo a default_statistics_targetvariável de configuração. O limite padrão é atualmente 100 entradas. Aumentar o limite pode permitir que estimativas de planejador mais precisas sejam feitas, principalmente para colunas com distribuições de dados irregulares, ao preço de consumir mais espaço pg_statistice um pouco mais de tempo para calcular as estimativas. Por outro lado, um limite inferior pode ser suficiente para colunas com distribuições de dados simples.

Muitas vezes tenho tabelas com alguns valores comuns e muitos valores raros. Ou o contrário, então o limite certo dependerá. Para aqueles que não usaram SET STATISTICS, ele permite definir a taxa de amostragem como um número alvo de entradas. O padrão é 100, então 1000 deve ser uma fidelidade mais alta. Aqui está o que parece:

ALTER TABLE assembly_prods 
    ALTER COLUMN assembly_id
    SET STATISTICS 1000;

Você pode usar SET STATISTICSem uma tabela ou índice. Aqui está um artigo interessante sobre índices:

https://akorotkov.github.io/blog/2017/05/31/alter-index-weird/

Observe que a documentação atual lista os SET STATISTICSíndices.

Então, experimentei limites de 1, 10, 100, 1000 e 10.000 e obtive esses resultados de uma tabela com 467.767 linhas e 28.088 valores distintos:

Target   Estimate  Difference  Missing
     1   13,657    14,431      51%
    10   13,867    14,221      51%
   100   13,759    14,329      51%
 1,000   24,746     3,342      12%
10,000   28,088         0       0%

Obviamente, você não pode tirar conclusões gerais de um caso, mas SET STATISTICSparece muito útil e ficarei feliz em tê-lo em minha mente. Estou tentado a aumentar um pouco o alvo em geral, pois suspeito que isso ajudaria em muitos dos casos em nosso sistema.

postgresql distinct
  • 1 1 respostas
  • 980 Views

1 respostas

  • Voted
  1. Best Answer
    Laurenz Albe
    2019-10-01T18:44:53+08:002019-10-01T18:44:53+08:00

    Primeiro, uma observação: sua consulta poderia ser escrita de forma mais simples como

    SELECT count(DISTINCT assembly_id) FROM assembly_prods;
    

    Além disso, sua consulta de estatísticas está errada, pois n_disticttambém pode ser negativa. Você deve consultar:

    SELECT CASE WHEN s.n_distinct < 0
                THEN - s.n_distinct * t.reltuples
                ELSE s.n_distinct
           END AS n_distinct
    FROM pg_class t
       JOIN pg_namespace n ON n.oid = t.relnamespace
       JOIN pg_stats s ON t.relname = s.tablename
                          AND n.nspname = s.schemaname
    WHERE s.schemaname = 'public'
      AND s.tablename = 'assembly_prods'
      AND s.attname = 'assembly_id';
    

    Para uma consulta simples como essa, as estatísticas devem conter uma boa estimativa.

    Se as estimativas estiverem erradas, tente ANALYZEa mesa. Isso também corrigirá os resultados de uma nova TRUNCATEtabela d. TRUNCATEnão faz com que o PostgreSQL analise automaticamente a tabela (pode haver espaço para melhorias aqui).

    Se isso melhorar os resultados, veja que a tabela é analisada com mais frequência configurando

    ALTER TABLE assembly_prods SET (autovacuum_analyze_scale_factor = 0.05);
    

    Também é possível definir autovacuum_analyze_scale_factorcomo 0 e aumentar autovacuum_analyze_thresholdpara a taxa de alteração diária da tabela.

    Se ANALYZEpor si só não melhorar a estimativa, aumente o tamanho da amostra:

    ALTER TABLE assembly_prods ALTER assembly_id SET STATISTICS 1000;
    

    Um novo ANALYZEdeve agora produzir melhores estimativas.

    Obter boas n_distinctestimativas para consultas mais complicadas se torna cada vez mais difícil. Às vezes , estatísticas estendidas melhorarão consideravelmente a estimativa.

    Até onde sei, o PostgreSQL v12 não traz nenhuma melhoria nessa área.

    • 5

relate perguntas

  • Posso ativar o PITR depois que o banco de dados foi usado

  • Práticas recomendadas para executar a replicação atrasada do deslocamento de tempo

  • Os procedimentos armazenados impedem a injeção de SQL?

  • Sequências Biológicas do UniProt no PostgreSQL

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

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