Pergunta

Eu atualmente trabalhando com um maior wikipedia-dump derivado do banco de dados PostgreSQL; ele contém cerca de 40 GB de dados. O banco de dados está sendo executado em um servidor HP ProLiant ML370 G5 com Suse Linux Enterprise Server 10; Eu estou consultando-lo do meu laptop através de uma rede privada gerida por um roteador D-Link simples. Eu atribuído DHCP estático IPs (privado) para ambos laptop e servidor.

De qualquer forma, do meu laptop, usando pgAdmin III, I enviar alguns comandos SQL / consultas; alguns destes são CREATE INDEX, DROP INDEX, DELETE, SELECT, etc. Às vezes eu enviar um comando (como CREATE INDEX), ele retorna, dizendo-me que a consulta foi executada perfeitamente, etc. No entanto, o processo postmaster designado para tal comando parece permanecer dormindo no servidor. Agora, eu realmente não me importo isso, pois eu digo para mim mesmo que o PostgreSQL mantém um pool de postmasters prontos para consultas de processo. No entanto, se esse processo consome 6 GB de que 9,4 GB RAM atribuído, eu preocupação (e fá-lo para o momento). Agora, talvez este é um cache de dados que são mantidos na memória [compartilhada] no caso de outra consulta acontece a necessidade de usar os mesmos dados, mas eu não sei.

Outra coisa está me incomodando.

Eu tenho 2 tabelas. Um deles é a página mesa; Eu tenho um índice em sua page_id coluna. O outro é o pagelinks tabelas que tem o pl_from coluna que referências nada ou uma variável no page.page_id coluna; ao contrário do page_id coluna, o pl_from não tem nenhum índice (ainda). Para lhe dar uma ideia da dimensão das tabelas e da necessidade de me para encontrar uma solução viável, página tabela tem 13,4 milhões de linhas (depois eu apaguei aqueles que eu não preciso), enquanto o pagelinks tabela tem 293 milhões.

Eu preciso executar o seguinte comando para limpar o pagelinks mesa de algumas de suas linhas inúteis:

DELETE FROM pagelinks USING page WHERE pl_from NOT IN (page_id);

Então, basicamente, eu desejo para livrar o pagelinks tabela de todas as ligações provenientes de uma página não no página mesa. Mesmo depois de desativar os loops aninhados e / ou varreduras seqüenciais, o otimizador de consulta sempre me dá a "solução" seguinte:

Nested Loop  (cost=494640.60..112115531252189.59 rows=3953377028232000 width=6)
  Join Filter: ("outer".pl_from <> "inner".page_id)"
  ->  Seq Scan on pagelinks  (cost=0.00..5889791.00 rows=293392800 width=17)
  ->  Materialize  (cost=494640.60..708341.51 rows=13474691 width=11)
        ->  Seq Scan on page  (cost=0.00..402211.91 rows=13474691 width=11)

Parece que tal tarefa levaria mais de semanas para ser concluído; Obviamente, isso é inaceitável. Parece-me que eu seria muito melhor que usar o page_id índice para fazer a sua coisa ... mas é um otimizador de teimoso e eu poderia estar errado.

Foi útil?

Solução 2

Na verdade, eu decidi criar uma tabela temporária para acelerar a execução da consulta:

CREATE TABLE temp_to_delete AS(
    (SELECT DISTINCT pl_from FROM pagelinks) 
        EXCEPT 
    (SELECT page_id FROM page));
DELETE FROM pagelinks USING temp_to_delete 
    WHERE pagelinks.pl_from IN (temp_to_delete.pl_from);

Surpreendentemente, esta consulta concluída em cerca de 4 horas enquanto a consulta inicial tinha permaneceu ativo por cerca de 14hrs antes de eu decidi matá-lo. Mais especificamente, a exclusão devolvidos:

Query returned successfully: 31340904 rows affected, 4415166 ms execution time.

Quanto à primeira parte da minha pergunta, parece que o processo postmaster de fato mantém algumas informações em cache; quando outra consulta requer informações não no cache e um pouco de memória (RAM), o cache é esvaziado. E os postmasters são, de facto, mas um conjunto de processo.

Ele também ocorreu-me que o gnome-system-monitor é um mito pois dá informações incompletas e é inútil no valor informativo. É principalmente devido a esta aplicação que eu tenho sido tão confuso ultimamente; por exemplo, não se considera o uso de memória de outros usuários (como o usuário postgres!) e até mesmo me diz que eu tenho 12 GB de RAM esquerda quando isso é tão falso. Assim, eu tentei um par de monitores do sistema para que eu gostaria de saber como o PostgreSQL está usando seus recursos, e parece que ¡¡Xosview é de fato uma ferramenta válida.

Espero que isso ajude!

Outras dicas

Para sua segunda pergunta; você poderia tentar criar uma nova tabela com apenas os registros que você precisa com um CREATE TABLE AS declaração; Se a nova tabela é suficientemente pequena, pode ser faster- mas pode não ajuda qualquer um.

Seu processo postmaster vai ficar lá enquanto a conexão com o cliente é aberta. Será pgadmin fechar a conexão? Eu não sei.

Memória usada poderia ser shared_buffers (verifique as suas definições de configuração) ou não.

Agora, a consulta. Para operações de manutenção grandes como este, sinta-se livre para definir work_mem a algo grande como alguns GB. Parece que você tem um monte de RAM, para usá-lo.

set work_mem para '4GB'; EXPLIQUE DELETE FROM pagelinks ONDE pl_from NOT IN (page_id SELECT FROM página);

Deve SEQ página varredura, mistura-lo, e seq pagelinks digitalização, espreitar no hash para verificar se há page_ids. Deve ser bastante rápido (muito mais rápido do que 4 horas!), Mas você precisa de um grande work_mem para o hash.

Mas desde que você excluir uma parcela significativa de sua mesa, pode ser mais rápido do que fazê-lo como este:

CREATE TABLE pagelinks2 AS SELECT * FROM um pagelinks um JOIN páginas B no a.pl_from = b.page_id;.

(você pode usar uma junção simples em vez de IN)

Você também pode adicionar um ORDER BY sobre esta consulta, e sua nova tabela será bem ordenada no disco para acesso ideal mais tarde.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top