Estou enfrentando degradação de desempenho e uso crescente de armazenamento como resultado de registros novos e atualizados frequentes, causando fragmentação de índice e armazenamento.
VÁCUO não ajuda muito.
Infelizmente CLUSTER não é uma opção, pois causa tempo de inatividade e pg_repack não está disponível para AWS RDS.
Estou procurando alternativas hacky para CLUSTER. Um que parece funcionar bem nos meus testes locais é:
begin;
create temp table tmp_target as select * from target;
delete from target;
insert into target select * from tmp_target order by field1 asc, field2 desc;
drop table tmp_target;
commit;
A ordenação dos ctid
looks está correta com:
select ctid, field1, field2 from target order by ctid;
A questão é: isso parece bom? Vai bloquear a target
tabela para SELECT
consultas que causam tempo de inatividade nos aplicativos? Existe uma maneira de listar os bloqueios envolvidos na transação?
Relacionado a consultas somente leitura de bloqueio de comando de cluster na réplica
Se é apenas sobre o inchaço da mesa,
VACUUM FULL
é a ferramenta para fazê-lo. (VACUUM
só reduz o arquivo físico se ele puder truncá-lo oportunamente no final.) No entanto,VACUUM FULL
também recebe um bloqueio exclusivo na tabela, assim comoCLUSTER
.Para fazer o mesmo sem bloqueio exclusivo pg_repack é a ferramenta que você procura. É lamentável que a Amazon não pareça permitir isso.
As soluções manuais introduzem todos os tipos de curvas e condições de corrida. Você precisaria especificar sua tabela e possíveis padrões de acesso exatamente antes de podermos discutir a melhor solução.
Sua solução atual não é boa de qualquer maneira. Você faz a operação de classificação após excluir todas as linhas (bloqueando-as), o que não diminuirá o tempo de inatividade (a duração do bloqueio) para
SELECT
consultas.Se você não tiver acesso de gravação simultâneo e nenhum objeto dependente , isso pode ser melhor:
Classifique em segundo plano antes de pegar o cadeado.
Estritamente falando,
INSERT
semORDER BY
é livre para escrever linhas em qualquer ordem física. Praticamente, porém, ele copiará a ordem física atual da tabela temporária com um simplesSELECT * FROM
(ouTABLE
abreviado).Use
TRUNCATE
em vez deDELETE
, que é mais rápido para tabelas grandes. Esteja ciente de algumas implicações comoTRUNCATE
não funciona com restrições FK. Leia o manual para cobertura completa.Você pode querer descartar os índices existentes logo antes
TRUNCATE
e recriar depoisINSERT
para tornar isso mais rápido.Relacionado:
O pg_repack já está disponível no RDS.