Domanda

Ho appena finito di trasferire il maggior numero possibile di dati sulla struttura dei collegamenti riguardanti Wikipedia (in inglese). Fondamentalmente, ho scaricato un sacco di dump SQL dal ultimo repository di dump di wikipedia . Dato che sto usando PostgreSQL invece di MySQL, ho deciso di caricare tutti questi dump nel mio db usando shell pipeline comandi .

Comunque, una di queste tabelle ha 295 milioni di righe: la tabella pagelink ; contiene tutti i collegamenti ipertestuali all'interno del wiki. Dal mio laptop, usando pgAdmin III, ho inviato il seguente comando al mio server di database (un altro computer):

SELECT pl_namespace, COUNT(*) FROM pagelinks GROUP BY (pl_namespace);

È stato lì per un'ora o giù di lì adesso. Il fatto è che il postmaster sembra divorare sempre di più il mio spazio HD molto limitato. Penso che abbia mangiato circa 20 GB a partire da ora. In precedenza avevo giocato con il file postgresql.conf per dargli una maggiore flessibilità delle prestazioni (ovvero lasciarlo usare più risorse) perché è in esecuzione con 12 GB di RAM. Penso di aver sostanzialmente quadruplicato la maggior parte dei byte e tali variabili correlate di questo file pensando che avrebbe usato più RAM per fare le sue cose.

Tuttavia, il db non sembra usare molta RAM. Utilizzando il monitor di sistema Linux, sono in grado di vedere che il postmaster utilizza 1,6 GB di memoria condivisa (RAM). Ad ogni modo, mi chiedevo se potreste aiutarmi a capire meglio cosa sta facendo perché sembra che non capisca davvero come PostgreSQL utilizza le risorse HD .

Per quanto riguarda la metastruttura dei database di Wikipedia, forniscono un buon schema che può essere utile o addirittura di tuo interesse.

Sentiti libero di chiedermi maggiori dettagli, grazie.

È stato utile?

Soluzione

Probabilmente è il GROUP BY a causare il problema. Per eseguire il raggruppamento, il database deve ordinare le righe per riunire gli elementi duplicati. Un indice probabilmente non aiuterà. Un calcolo back-of-the-envelope:

Supponendo che ogni riga occupi 100 byte di spazio, ovvero 29.500.000.000 di byte, o circa 30 GB di spazio di archiviazione. Non può contenere tutto ciò che è in memoria, quindi il tuo sistema si sta schiantando, il che rallenta le operazioni di un fattore di 1000 o più. Il tuo spazio HD potrebbe scomparire nello spazio di scambio, se utilizza file di scambio.

Se devi eseguire questo calcolo una sola volta, prova a suddividerlo in sottoinsiemi più piccoli di dati. Supponendo che pl_namespace sia numerico e sia compreso tra 1-295 milioni, provare qualcosa del genere:

SELECT pl_namespace, COUNT(*)
FROM pagelinks
WHERE pl_namespace between 1 and 50000000
GROUP BY (pl_namespace);

Quindi fai lo stesso per 50000001-100000000 e così via. Combina le tue risposte insieme utilizzando UNION o semplicemente tabula i risultati con un programma esterno. Dimentica ciò che ho scritto su un indice che non aiuta GROUP BY; qui, un indice aiuterà la clausola WHERE.

Altri suggerimenti

Cosa esattamente afferma che richiede solo 9.5 MB di RAM? Mi sembra improbabile: la memoria condivisa quasi sicuramente è RAM che viene condivisa tra diversi processi Postgres. (Da quello che ricordo, ogni cliente finisce come un processo separato, anche se è passato un po 'di tempo quindi potrei sbagliarmi molto.)

Hai un indice nella colonna pl_namespace ? Se ci sono un sacco di risultati distinti, potrei immaginare che la query sia piuttosto pesante su una tabella di 295 milioni di righe senza indice. Detto questo, 10 GB sono davvero tanti da ingoiare. Sai in quali file sta scrivendo?

Ok, ecco il senso:

la clausola GROUP BY ha reso l'indice 'non valido, quindi il postmaster (processo del server postgresql) ha deciso di creare un gruppo di tabelle (23 GB di tabelle) che si trovavano nella directory $ PGDATA / base / 16384 / pgsql_tmp.

Quando ho modificato il file postgresql.conf, avevo dato il permesso a postgreSQL di usare 1,6 GB di RAM (che raddoppierò perché ha accesso a 11,7 GB di RAM); il processo postmaster stava effettivamente utilizzando fino a 1,6 GB di RAM, ma non era abbastanza, quindi la directory pgsql_tmp.

Come sottolineato da Barry Brown, poiché stavo solo eseguendo questo comando SQL per ottenere alcune informazioni statistiche sulla distribuzione dei collegamenti tra pagelinks.namespaces , avrei potuto interrogare un sottoinsieme di i 296 milioni di pagelink (questo è ciò che fanno per i sondaggi).

Quando il comando ha restituito il set di risultati, tutte le tabelle temporanee sono state automaticamente eliminate come se nulla fosse accaduto.

Grazie per il vostro aiuto ragazzi!

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