Melhor Desempenho em Big Update no Postgresql (Continuação...)

Posted Over 10 years ago. Visible to the public.

SEQUÊNCIA

VAMOS AO CARD

Em continuidade ao card anterior, aquele update de 70 minutos que havia já reduzido para 32 minutos foi diminuído ao final para apenas 4 minutos. Não é mágica, é tecnologia!

A fonte que me motivou foi a mesma do card anterior

In PostgreSQL's MVCC model, an UPADATE means to create a new row version and mark the old one as deleted. That's about as expensive as an INSERT and a DELETE combined. Plus, it leaves you with a lot of dead tuples. Since you are updating the whole table anyway, it would be faster overall to just create a new table and drop the old one.

E é isto que eu resolvi fazer. Ao precisar unir duas tabelas A e B, acrescentando algumas colunas de B em A, um update direto em A demorava 70 minutos com índices e 32 minutos sem índices. Agora fiz um A left join B mandando o resultado para uma nova tabela A_new (que já tem seus tipos definidos automaticamente, olha que bom!), ao final apagando A e então renomeando A_new para A.

CREATE TABLE A_new AS
SELECT A.*, B.campo1, B.campo2
FROM A
LEFT JOIN B ON A.referencia = B.id;

A solução super simples só não foi mais simples para mim por ser indicada para tabelas que não possuem dependências. No meu caso precisei me dar ao trabalho de apagar todos índices da tabela A, todas foreign keys que referenciavam A, todas foreign keys de A que referenciavam outras tabelas, e todas as views que utilizavam A. E depois recriá-las todas referenciando A_new (antes ou depois de renomear, tanto faz). Após comprovar a diferença de desempenho achei o esforço de escrita válido.

Fonte: http://dba.stackexchange.com/questions/41059/optimizing-bulk-update-performance-in-postgresql Show archive.org snapshot

Bruno Vieira
Last edit
Over 9 years ago
Bruno Vieira
Posted by Bruno Vieira to ZeroGlosa (2013-11-05 21:13)