Longo ATUALIZAÇÃO no PostgreSQL

votos
6

I ter sido executado um UPDATE em uma tabela contendo 250 milhões de linhas com índice de 3 '; Essa atualização usa outra tabela contendo 30 milhões de linhas. Ele foi executado por cerca de 36 horas agora. Eu estou querendo saber se a sua é uma maneira de descobrir o quão próximo está a ser feito para se pretende levar um milhão de dias para fazer a sua coisa, eu vou matá-lo; No entanto, se ele só precisa de mais um dia ou dois, eu vou deixá-lo correr. Aqui está o comando query:

UPDATE pagelinks SET pl_to = page_id
    FROM page
    WHERE 
        (pl_namespace, pl_title) = (page_namespace, page_title)
        AND
        page_is_redirect = 0
;

A EXPLICAR não é a questão aqui e só eu mencionar que têm vários índices grande da tabela do para justificar um tanto quanto tempo leva para atualizá-lo. Mas aqui é o EXPLICAR de qualquer maneira:

Merge Join  (cost=127710692.21..135714045.43 rows=452882848 width=57)
  Merge Cond: ((outer.page_namespace = inner.pl_namespace) AND (outer.?column4? = inner.?column5?))
  ->  Sort  (cost=3193335.39..3219544.38 rows=10483593 width=41)
        Sort Key: page.page_namespace, (page.page_title)::text
        ->  Seq Scan on page  (cost=0.00..439678.01 rows=10483593 width=41)
              Filter: (page_is_redirect = 0::numeric)
  ->  Sort  (cost=124517356.82..125285665.74 rows=307323566 width=46)
        Sort Key: pagelinks.pl_namespace, (pagelinks.pl_title)::text
        ->  Seq Scan on pagelinks  (cost=0.00..6169460.66 rows=307323566 width=46)

Agora eu também enviou uma consulta de comando paralelo, a fim de queda em um dos pagelinks índices; é claro que está à espera para a atualização ao fim (mas eu senti como tentar de qualquer maneira!). Daí, eu não pode selecionar qualquer coisa de pagelinks por medo de danificar os dados (a menos que você acha que seria seguro para matar o processo postmaster DROP INDEX?).

Então, eu estou querendo saber se a sua é uma tabela que iria manter o controle da quantidade de tuplas mortas ou algo para Seria bom saber o quão rápido ou quão longe o UPDATE está na conclusão de sua tarefa.

Thx (PostgreSQL não é tão inteligente quanto eu pensava, mas precisa de heurística)

Publicado 07/01/2009 em 21:09
fonte usuário
Em outras línguas...                            


3 respostas

votos
4

Você leu a documentação do PostgreSQL para " Usando EXPLICAR ", para interpretar a saída você está mostrando?

Eu não sou um usuário regular PostgreSQL, mas eu só li que doc, e em seguida, em comparação com a EXPLAINsaída que você está mostrando. Sua UPDATEconsulta parece estar usando nenhum índice, e é forçado a fazer mesa de exames para classificar tanto pagee pagelinks. O tipo é, sem dúvida, grande o suficiente para precisar de arquivos temporários em disco, que eu acho que são criados sob o seu temp_tablespace.

Então eu vejo as páginas de banco de dados estimados ler. O de nível superior do que EXPLAINa saída diz (cost=127710692.21..135714045.43). As unidades aqui são em disco I / O acessa. Então ele vai para acessar o disco mais de 135 milhões de vezes para fazer isso UPDATE.

Note-se que até mesmo discos 10.000 rpm com 5ms tempo de busca pode alcançar na melhor das hipóteses 200 I / O operações por segundo em condições ideais. Isto significaria que o UPDATElevaria 188 horas (7,8 dias) de disco I / O, mesmo que você poderia sustentar disco saturada I / O para esse período (ou seja contínua lê / escreve sem quebras). Isso é impossível, e eu esperaria o rendimento real para estar fora por pelo menos uma ordem de magnitude, especialmente desde que você não tem nenhuma dúvida vindo a utilizar este servidor para todos os tipos de outro trabalho no mesmo período. Então eu acho que você é apenas uma fração do caminho através de seu UPDATE.

Se fosse comigo, eu teria matado esta consulta no primeiro dia, e encontrou uma outra maneira de realizar o UPDATEque fez melhor uso de índices e não exigem ordenação em disco. Você provavelmente não pode fazê-lo em uma única instrução SQL.

Quanto ao seu DROP INDEX, eu acho que é simplesmente bloquear, à espera de acesso exclusivo para a mesa, e enquanto é neste estado que eu acho que você provavelmente pode matá-lo.

Respondeu 09/01/2009 em 19:55
fonte usuário

votos
0

Você precisa de índices ou, como Bill apontou, ele terá de fazer varreduras seqüenciais em todas as mesas.

CREATE INDEX page_ns_title_idx on page(page_namespace, page_title);
CREATE INDEX pl_ns_title_idx on pagelink(pl_namespace, pl_title);
CREATE INDEX page_redir_idx on page(page_is_redirect);
Respondeu 09/01/2009 em 20:13
fonte usuário

votos
1

Isso é muito antiga, mas se você quiser uma maneira para que você Monitores sua atualização ... Lembre-se que as sequências são afetados globalmente, assim você só pode criar um para Monitores essa atualização em outra sessão, fazendo isso:

create sequence yourprogress; 

UPDATE pagelinks SET pl_to = page_id
    FROM page
    WHERE 
        (pl_namespace, pl_title) = (page_namespace, page_title)
        AND
        page_is_redirect = 0 AND NEXTVAL('yourprogress')!=0;

Em seguida, em outra sessão apenas fazer isso (não se preocupe com as transacções, como as sequências são afetados globalmente):

select last_value from yourprogress;

Isto irá mostrar quantas linhas estão sendo afetadas, para que possa estimar quanto tempo você vai tomar.

Ao acabar reiniciar sua seqüência para fazer outra tentativa:

alter sequence yourprogress restart with 1;

Ou apenas soltá-lo:

drop sequence yourprogress;
Respondeu 20/09/2018 em 11:09
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more