2013-09-02 21 views
27

È più efficiente creare un indice dopo che il caricamento dei dati è stato completato o prima o non è importante?Il modo più efficiente per creare un indice in Postgres

Ad esempio, supponiamo di avere 500 file da caricare in un DB Postgres 8.4. Ecco i due scenari di creazione dell'indice che potrei utilizzare:

  1. Creare un indice quando viene creata una tabella, quindi caricare ciascun file nella tabella; oppure
  2. Crea un indice dopo che tutti i file sono stati caricati nella tabella.

I dati della tabella sono circa 45 gigabyte. L'indice è di circa 12 gigabyte. Sto usando un indice standard. Si è creato così:

CREATE INDEX idx_name ON table_name (column_name); 

mio caricamento dei dati utilizza COPY FROM.

Una volta caricati tutti i file, non si verificheranno aggiornamenti, eliminazioni o carichi aggiuntivi sulla tabella (è un valore giornaliero di dati che non cambierà). Quindi volevo chiedere quale scenario sarebbe più efficiente? Il test iniziale sembra indicare che caricare tutti i file e quindi creare l'indice (scenario 2) è più veloce, ma non ho fatto un confronto scientifico dei due approcci.

risposta

43

L'osservazione è corretta: è molto più efficiente caricare i dati prima e solo poi creare indice. Motivo per questo è che gli aggiornamenti dell'indice durante l'inserimento sono costosi. Se crei un indice dopo che tutti i dati sono presenti, è molto più veloce.

Va anche oltre: se è necessario importare grandi quantità di dati nella tabella indicizzata esistente, è spesso più efficiente eliminare prima l'indice esistente, importare i dati e quindi ricreare nuovamente l'indice.

Uno svantaggio della creazione dell'indice dopo l'importazione è che la tabella deve essere bloccata e ciò potrebbe richiedere molto tempo (non verrà bloccato in uno scenario opposto). Ma, in PostgreSQL 8.2 e versioni successive, è possibile utilizzare CREATE INDEX CONCURRENTLY, che non blocca la tabella durante l'indicizzazione (con alcune avvertenze).

+0

Bene, quando il tavolo è bloccato nessuno può leggere o scrivere, il che può essere molto fastidioso, anche di notte. Stai meglio usando CREATE INDEX CONCORRENTAMENTE – mvp

+0

@BradTilley: ho pensato che fosse una nuova funzionalità, ma PostgreSQL 8.4 [lo supporta] (http://www.postgresql.org/docs/8.4/static/sql-createindex.html). – mvp

+4

"* quando la tabella è bloccata nessuno può leggere o scrivere *" - Non penso che sia vero. Quando è in esecuzione 'CREATE INDEX', la tabella può ancora essere letta, ma non aggiornata se non sbaglio. –

Problemi correlati