PostgreSQL consulta Optimization e do Processo Postmaster

votos
1

Eu atualmente trabalhando com um maior wikipedia-dump derivada 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 simples roteador D-Link. Eu atribuído DHCP estático IPs (privados) 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 processar consultas. No entanto, se este processo consome 6 GB de que 9,4 GB RAM atribuídos, eu me preocupo (e fá-lo para o momento). Agora, talvez este é um cache de dados que é mantida na memória [compartilhada] no caso de outra consulta acontece precisar usar os mesmos dados, mas eu não sei.

Outra coisa está me incomodando.

Eu tenho 2 tabelas. Um deles é a página de mesa; Eu tenho um índice em seu page_id coluna. A outra é a pagelinks tabelas que contém 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 possui um í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 na 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.

Publicado 05/01/2009 em 20:59
fonte usuário
Em outras línguas...                            


3 respostas

votos
1

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 quer ajudar.

Respondeu 05/01/2009 em 22:14
fonte usuário

votos
1

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, DELETE retornado:

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.

Também me ocorreu 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 confusa 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 isto ajude!

Respondeu 06/01/2009 em 01:48
fonte usuário

votos
0

Seu processo postmaster vai ficar lá enquanto a conexão com o cliente é aberta. Faz 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.

definir work_mem para '4GB'; EXPLAIN DELETE FROM pagelinks ONDE pl_from NOT IN (SELECT page_id a partir da página);

Deve página seq digitalização, hash-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:

CRIE pagelinks2 TABLE AS SELECT * FROM um pagelinks uma junção páginas b SOBRE 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.

Respondeu 28/10/2009 em 00:25
fonte usuário

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