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 / 330877
Accepted
George G
George G
Asked: 2023-09-05 01:22:47 +0800 CST2023-09-05 01:22:47 +0800 CST 2023-09-05 01:22:47 +0800 CST

PostgreSQL - Dividindo a tabela em duas (atual e histórica)

  • 772

Estou analisando um aplicativo legado que gerencia objetos armazenados em um banco de dados PostgreSQL.

Cada objeto possui vários conjuntos de propriedades que são armazenados como objetos JSONB. Cada um desses conjuntos de propriedades descreve um aspecto diferente do objeto (pode haver de 1 a 10 conjuntos de propriedades por objeto).

Em relação a isso, diferentes departamentos geralmente se preocupam apenas com alguns desses conjuntos de propriedades (aspectos), portanto o número de conjuntos de propriedades varia dependendo de quem está envolvido durante o ciclo de vida de cada objeto.

Cada vez que algo muda em uma propriedade definida pelo aplicativo front-end (que está além do meu controle), ele é enviado de volta ao banco de dados como um novo documento JSON.

No momento, a tabela (para efeito de argumentação) está estruturada da seguinte forma:

TABLE x (
  object_id INTEGER,
  aspect_id INTEGER,
  doc_ts TIMESTAMP,
  doc JOSNB,
  PRIMARY KEY (object_id, aspect_id, doc_ts)
)

A entrada de dados é tratada por um procedimento, que armazena uma cópia do documento em uma tabela, e tem a seguinte aparência:

CREATE OR REPLACE PROCEDURE ingest.generic_object(IN in_object_id integer, IN in_aspect_id integer, IN in_doc_ts TIMESTAMP,  IN in_doc JSONB DEFAULT NULL::JSONB)
 LANGUAGE plpgsql
AS $procedure$
  BEGIN
      INSERT INTO ingest.x ( object_id, aspect_id, doc_ts, doc) 
      VALUES (in_object_id, in_aspect_id, in_doc_ts, in_doc)
      ;
  END;
$procedure$;

Agora vamos passar para o problema que estou tentando resolver. Esta tabela continua crescendo com o tempo e pode ficar muito grande, muito rapidamente. O processo de manutenção mantém APENAS um registro para cada combinação de object_id e aspecto_id (ou seja, apenas aquele com o valor doc_ts mais recente) e leva muito tempo para ser executado.

Estou pensando em dividir os dados em duas tabelas. Como:

TABLE ingest.x (
  object_id INTEGER,
  aspect_id INTEGER,
  doc_ts TIMESTAMPZ,
  doc JOSNB,
  PRIMARY KEY (object_id, aspect_id, doc_ts)
);

TABLE ingest.x_history (
  object_id INTEGER,
  aspect_id INTEGER,
  doc_ts TIMESTAMP,
  doc JOSNB,
  PRIMARY KEY (object_id, aspect_id, doc_ts)
);

E então altere a função de ingestão para algo parecido com:

CREATE OR REPLACE PROCEDURE ingest.generic_object(IN in_object_id integer, IN in_aspect_id integer, IN in_doc_ts TIMESTAMP, IN in_doc JSONB DEFAULT NULL::JSONB)
 LANGUAGE plpgsql
AS $procedure$
  BEGIN
      WITH 
        dd AS (
          DELETE FROM ingest.x
          WHERE object_id= in_object_id
            AND aspect_id = in_aspect_id
          RETURNING *
        ), 
        di AS (
          INSERT INTO ingest.x_history ( object_id, aspect_id, doc_ts, doc) 
          SELECT object_id, aspect_id, doc_ts, doc FROM dd            
        )
      INSERT INTO ingest.x ( object_id, aspect_id, doc_ts, doc) 
      VALUES (in_object_id, in_aspect_id, in_doc_ts, in_doc)
      ;
  END;
$procedure$;

Isso me permitiria simplificar SIGNIFICATIVAMENTE o processo de limpeza, até:

TRUNCATE TABLE ingest.x_history;

Minhas perguntas são as seguintes:

  1. Considerando a alteração acima, o AUTOVACUUM levará a alguma reutilização do espaço ocupado pelos registros excluídos em ingest.x?

  2. Quais parâmetros de tabela ingest.xdevo ajustar para melhorar a reutilização do espaço liberado pelos registros excluídos? - Supondo que a resposta para 1 seja SIM. Tenho em mente o FILL FACTOR juntamente com limites de AUTOVACUUM mais direcionados.

  3. Você consegue ver uma abordagem alternativa para alcançar um processo de limpeza mais fácil e eficaz?

Observação:

  • Tudo isso está rodando no PostgreSQL v15
  • Os registros de documentos podem ser redigidos dezenas de vezes durante a fase de criação – primeiros dias. Depois, uma vez a cada dois dias/semanas durante o período de revisão. Mudanças podem acontecer depois disso, mas são muito raras.
  • Os dados brutos podem envelhecer muito rapidamente, e é por isso que TRUNCAR o histórico não é um problema.

Edição 1: Os documentos JSON variam entre 100kb e 2MB. Acredito que sejam direcionados ao TOAST. Além disso, o banco de dados está em um sistema de arquivos ZFS e, como tal, a compactação PostgreSQL está desativada, aproveitando a compactação ZFS.

Atenciosamente

postgresql-15
  • 1 1 respostas
  • 10 Views

1 respostas

  • Voted
  1. Best Answer
    Vérace
    2023-09-05T02:28:56+08:002023-09-05T02:28:56+08:00
      1. Considerando a alteração acima, o AUTOVACUUM levará a alguma reutilização do espaço ocupado pelos registros excluídos em ingest.x?

    Sim, vai - é para isso que serve o AUTOVACUUM - parar o inchaço da mesa!

      1. Quais parâmetros de tabela para ingest.x devo ajustar para melhorar a reutilização do espaço liberado pelos registros excluídos?

    "Ajustar" vários parâmetros da tabela depende do seu próprio uso, das suas próprias taxas de tabela INSERTe do tamanho dos registros. Este é outro parâmetro que pode influenciar o processo. A menos que você tenha uma pergunta mais específica sobre isso, é difícil dar uma resposta definitiva.UPDDATEDELETEfillfactor

    Esta é uma ciência completa - na seção Parâmetros de armazenamento da CREATE TABLEparte do manual, existem 17 parâmetros que começam com autovacuum_...e mais dois que começam com vacuum_....

      1. Você consegue ver uma abordagem alternativa para alcançar um processo de limpeza mais fácil e eficaz?

    A resposta para qualquer problema em ciência da computação normalmente é “Depende!”

    As tabelas de histórico são a solução "clássica" para esse problema e você pode, é claro, como diz, TRUNCATEelas (ou colocá-las em algum tipo de "armazenamento refrigerado"). Você também pode considerar PARTITIONsuas tabelas - você terá que ler sobre isso e ver se elas se adequam ao seu caso de uso específico.

    Além do Fine Manual, você também pode ler isto - um e-book do Postgrespro - pesos pesados ​​no mundo PostgreSQL que tem um capítulo inteiro sobre AUTOVACUUM, aqui (um e-book do Japão - um pouco mais antigo) também pode valer a pena dar uma olhada. Nenhum dos e-books trata de particionamento - o FM e seu mecanismo de busca favorito devem resolver o problema. O conceito relacionado de congelamento também é abordado nos e-books - mais uma vez, o livro do Postgrespro tem um capítulo inteiro!

    • 0

relate perguntas

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