Domanda

Attualmente sto lavorando con un database PostgreSQL derivato da dump di Wikipedia più grande; contiene circa 40 GB di dati. Il database è in esecuzione su un server HP Proliant ML370 G5 con Suse Linux Enterprise Server 10; Lo sto interrogando dal mio laptop su una rete privata gestita da un semplice router D-Link. Ho assegnato IP DHCP (privati) statici sia a laptop che a server.

Comunque, dal mio laptop, usando pgAdmin III, invio alcuni comandi / query SQL; alcuni di questi sono CREATE INDEX, DROP INDEX, DELETE, SELECT, ecc. A volte invio un comando (come CREATE INDEX), ritorna, mi dice che la query è stata eseguita perfettamente, ecc. Tuttavia, il processo postmaster assegnato a tale il comando sembra rimanere inattivo sul server. Ora, non mi dispiace davvero, perché dico a me stesso che PostgreSQL mantiene un pool di postmaster pronti a elaborare le query. Tuttavia, se questo processo ne consuma 6 GB, 9,4 GB RAM assegnata, mi preoccupo (e lo fa per il momento). Ora forse questa è una cache di dati che viene conservata nella memoria [condivisa] nel caso in cui un'altra query debba utilizzare quegli stessi dati, ma non lo so.

Un'altra cosa mi dà fastidio.

Ho 2 tavoli. Uno è la tabella pagina ; Ho un indice nella sua colonna page_id . L'altra è la pagelink che ha la colonna pl_from che non fa riferimento a nulla o a una variabile nella colonna page.page_id ; a differenza della colonna page_id , pl_from non ha ancora un indice. Per darti un'idea della scala delle tabelle e della necessità per me di trovare una soluzione praticabile, la tabella pagina ha 13,4 milioni di righe (dopo che ho eliminato quelle non necessarie) mentre La tabella pagelink ha 293 milioni.

Devo eseguire il comando seguente per pulire la tabella pagelink di alcune delle sue righe inutili:

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

Quindi, in sostanza, desidero eliminare la tabella pagelink di tutti i collegamenti provenienti da una pagina non nella tabella pagina . Anche dopo aver disabilitato i cicli nidificati e / o le scansioni sequenziali, Query Optimizer mi fornisce sempre la seguente "soluzione":

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)

Sembra che un tale compito richiederebbe più di settimane per essere completato; ovviamente, questo è inaccettabile. Mi sembra che preferirei di gran lunga usare l'indice page_id per fare le sue cose ... ma è un ottimizzatore testardo e potrei sbagliarmi.

È stato utile?

Soluzione 2

In effetti, ho deciso di CREARE una tabella temporanea per accelerare l'esecuzione della query:

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);

Sorprendentemente, questa query è stata completata in circa 4 ore mentre la query iniziale era rimasta attiva per circa 14 ore prima che decidessi di ucciderla. Più specificamente, il DELETE ha restituito:

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

Per quanto riguarda la prima parte della mia domanda, sembra che il processo postmaster mantenga effettivamente alcune informazioni nella cache; quando un'altra query richiede informazioni non presenti nella cache e parte della memoria (RAM), la cache viene svuotata. E i postmaster non sono altro che un pool di processi '.

Mi è anche venuto in mente che il gnome-system-monitor è un mito in quanto fornisce informazioni incomplete ed è privo di valore informativo. È principalmente dovuto a questa applicazione che sono stato così confuso ultimamente; per esempio, non considera l'utilizzo della memoria di altri utenti (come l'utente di postgres!) e mi dice persino che mi rimangono 12 GB di RAM quando questo è falso. Quindi, ho provato un paio di monitor di sistema perché mi piace sapere come postgreSQL sta usando le sue risorse, e sembra che xosview sia davvero uno strumento valido.

Spero che questo aiuti!

Altri suggerimenti

Alla tua seconda domanda; potresti provare a creare una nuova tabella con solo i record necessari con un'istruzione CREATE TABLE AS; se la nuova tabella è sufficientemente piccola, potrebbe essere più veloce, ma potrebbe non essere utile neanche.

Il tuo processo postmaster rimarrà lì finché la connessione al client sarà aperta. Pgadmin chiude la connessione? Non lo so.

La memoria utilizzata potrebbe essere shared_buffers (controlla le tue impostazioni di configurazione) oppure no.

Ora, la query. Per grandi operazioni di manutenzione come questa, sentiti libero di impostare work_mem su qualcosa di grande come pochi GB. Sembra che tu abbia molta RAM, quindi usalo.

imposta work_mem su '4GB'; SPIEGA ELIMINA DA pagelink DOVE pl_da NON IN (SELEZIONA page_id DA pagina);

Dovrebbe seq scan page, hash it e seq scan pagelink, sbirciare nell'hash per controllare page_ids. Dovrebbe essere abbastanza veloce (molto più veloce di 4 ore!) Ma hai bisogno di un grande work_mem per l'hash.

Ma poiché elimini una parte significativa della tabella, potrebbe essere più veloce farlo in questo modo:

CREA TABELLA pagelink2 COME SELEZIONA a. * DA pagelink a ISCRIVITI pagine b ON a.pl_from = b.page_id;

(puoi usare un semplice JOIN invece di IN)

Puoi anche aggiungere un ORDER BY a questa query e la tua nuova tabella verrà ordinata correttamente su disco per un accesso ottimale in seguito.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top