Perché PostgreSQL query di calo di prestazioni nel corso del tempo, ma ripristinato quando la ricostruzione dell'indice

StackOverflow https://stackoverflow.com/questions/2392982

Domanda

In base a questo pagina nel manuale, indexes don't need to be maintained. Tuttavia, ci sono in esecuzione con un tavolo PostgreSQL che ha un tasso continuo di updates, deletes e inserts che nel tempo (pochi giorni) vede un degrado significativo di query. Se eliminare e ricreare l'indice, la query prestazioni viene ripristinato.

Stiamo usando fuori le impostazioni della casella.
La tabella nel nostro test è attualmente inizi vuoto e cresce a mezzo milione di righe. Ha un gran fila (un sacco di campi di testo).

Siamo searching based of an index, not the primary key (ho confermato l'indice è in uso, almeno in condizioni normali)

La tabella viene utilizzato come un archivio permanente per un singolo processo. Utilizzando PostgreSQL su Windows con un client Java.

Sono disposto a rinunciare insert and update performance per mantenere le prestazioni delle query.

valutando riprogettare l'applicazione in modo che i dati sono sparsi in varie tabelle dinamiche in modo che ci permette di cadere e ricostruire gli indici periodicamente senza impattare l'applicazione. Tuttavia, come sempre, v'è un tempo di crisi per ottenere questo al lavoro e ho il sospetto che ci manca qualcosa di fondamentale nella nostra configurazione o utilizzo.

Abbiamo considerato forcing vacuuming e rebuild to run at certain times, ma ho il sospetto che il locking period for such an action would cause our query to block. Questo può essere un'opzione, ma ci sono alcuni in tempo reale (le finestre di 3-5 secondi) implicazioni che richiedono altri cambiamenti nel nostro codice.

Ulteriori informazioni: Tabella e l'indice

CREATE TABLE icl_contacts
(
  id bigint NOT NULL,
  campaignfqname character varying(255) NOT NULL,
  currentstate character(16) NOT NULL,
  xmlscheduledtime character(23) NOT NULL,
...
25 or so other fields.  Most of them fixed or varying character fiel  
...
  CONSTRAINT icl_contacts_pkey PRIMARY KEY (id)
)
WITH (OIDS=FALSE);
ALTER TABLE icl_contacts OWNER TO postgres;

CREATE INDEX icl_contacts_idx
  ON icl_contacts
  USING btree
  (xmlscheduledtime, currentstate, campaignfqname);

Analizzare:

Limit  (cost=0.00..3792.10 rows=750 width=32) (actual time=48.922..59.601 rows=750 loops=1)
  ->  Index Scan using icl_contacts_idx on icl_contacts  (cost=0.00..934580.47 rows=184841 width=32) (actual time=48.909..55.961 rows=750 loops=1)
        Index Cond: ((xmlscheduledtime < '2010-05-20T13:00:00.000'::bpchar) AND (currentstate = 'SCHEDULED'::bpchar) AND ((campaignfqname)::text = '.main.ee45692a-6113-43cb-9257-7b6bf65f0c3e'::text))

E, sì, sono consapevole ci sono una varietà di cose we could do to normalize and improve the design of this table. Alcune di queste opzioni potrebbero essere a nostra disposizione.

Il mio obiettivo in questa domanda è su how PostgresQL is managing the index and query over time (understand why, not just fix) comprensione. Se dovesse essere fatto nel corso o significativamente refactoring, ci sarebbe un sacco di cambiamenti.

È stato utile?

Soluzione

Sistema di vuoto dovrebbe fare il trucco, a condizione è stata configurata per la vostra prestazione desiderata.

Note: VACUUM FULL: questo ricostruirà statistiche di tabella e carichi di bonifica di spazio su disco. Si blocca l'intera tabella.

VUOTO: questo ricostruirà statistiche di tabella e recuperare un po 'di spazio su disco. Può essere eseguito in parallelo con sistema di produzione, ma genera un sacco di IO che possono influire sulle prestazioni.

ANALISI: questo ricostruirà di query statistiche planner. Questo è innescato dal vuoto, ma può essere eseguito da solo.

note dettagliate trovato qui

Altri suggerimenti

Per quanto riguarda le prestazioni, utilizzando stringhe per memorizzare ora e lo stato informazioni è piuttosto un collo di bottiglia. Prima di tutto, indici su testi sono estremamente inefficiente, confrontando due volte sulle stesse esigenze giorno almeno 11 confronto (nel formato che hai utilizzato), tuttavia, utilizzando il tipo può essere ridotto a un semplice confronto di tempo. Ciò effettua anche la dimensione dell'indice, e un grande indice è difficile da cercare su, e il db non tenerlo in memoria. Stesse considerazioni valgono per la colonna Stato. Se rappresenta un piccolo insieme di stati, si consiglia di utilizzare interi numeri mappate agli stati, questo ridurrà i nodi dell'indice - e la dimensione dell'indice di conseguenza. Inoltre, questo indice sarà inutile anche utilizzando theese tipi built-in, se non si specifica il tempo effettivo nella query.

Questa odora indice gonfiare a me. I'l fare riferimento a questa pagina

http://www.postgresql.org/docs/8.3/ static / routine reindex.html

che dice in basso:

  

Inoltre, per gli indici B-tree un   index appena costruito è alquanto   più veloce per l'accesso di uno che ha   stato aggiornato più volte, a causa   logicamente pagine adiacenti sono di solito   anche fisicamente adiacenti in una nuova   Indice costruito. (Questa considerazione fa   attualmente non si applicano ai non-B-tree   indici.) potrebbe essere utile per   reindicizzare periodicamente solo migliorare   velocità di accesso.

Il che non sembrano essere in conflitto con la pagina che fa riferimento dicendo che gli indici "non necessitano di manutenzione o messa a punto".

Hai provato "creare l'indice contemporaneamente"?

E 'la '2010-05-20T13: 00: 00.000'? Valore che xmlscheduledtime viene paragonato a, parte di SQL, o fornito come parametro

Quando si pianifica il modo per eseguire la query, dicendo che un campo deve essere inferiore a un parametro fornito con un valore ancora sconosciuto non dà PostgreSQL molto per andare avanti. Non so se che ti corrispondono quasi tutte le righe, o quasi nessuna delle righe.

come le statistiche usi planner aiuta moltissimo quando si cerca di capire il motivo per cui il vostro database utilizza i piani che è.

Si potrebbe ottenere una migliore selezionare le prestazioni modificando l'ordine dei campi di tale indice complesso, o la creazione di un nuovo indice, con i campi ordinati (campaignfqname, CurrentState, xmlscheduledtime) da allora l'indice vi porterà direttamente al nome FQ campagna e dello stato attuale che ti interessa, e l'indice di scansione su tutta la gamma xmlscheduledtime sarete tutti file che stai cercando.

Questo è un caso da manuale. Si dovrebbe configurazione autovacuum ad essere molto più aggressivo.

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