Pergunta

Fui correndo um UPDATE em uma tabela contendo 250 milhões de linhas com 3 índice '; 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-consulta comando:

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 é o problema aqui e só eu mencionar que têm vários índices grande da tabela a fim de um pouco justificar o tempo que leva para atualizá-lo. Mas aqui é o EXPLICAR 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 GOTA 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ísticas)

Foi útil?

Solução

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 o EXPLAIN saída você está mostrando. Sua consulta UPDATE parece estar usando nenhum índice, e é forçado a fazer mesa de exames para classificar tanto page e 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 seu temp_tablespace.

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

Note que os discos 10.000 rpm Mesmo 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 seu UPDATE levaria 188 horas (7,8 dias) de disco I / O, mesmo que você poderia sustentar disco I / O para esse período saturada (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 a UPDATE que fez melhor uso de índices e não exigir em disco de classificação. Você provavelmente não pode fazê-lo em uma única instrução SQL.

Quanto à sua 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.

Outras dicas

Este é 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.

Com apenas final reiniciar sua seqüência para fazer outra tentativa:

alter sequence yourprogress restart with 1;

Ou apenas soltá-lo:

drop sequence yourprogress;

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);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top