Warum funktioniert PostgresQL Abfrage Leistungsabfall im Laufe der Zeit, aber gestellt, wenn Index Wiederaufbau

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

Frage

Nach diesem im Handbuch, indexes don't need to be maintained. Wir sind jedoch mit einem PostgresQL Tabelle ausgeführt, die eine kontinuierliche Rate von updates, deletes und inserts, dass im Laufe der Zeit hat (wenige Tage) sieht eine deutliche Abfrage Abbau. Wenn wir den Index löschen und neu erstellen, die Abfrageleistung gestellt wird.

Wir verwenden aus den Box-Einstellungen.
Die Tabelle in unserem Test beginnt zur Zeit leer und wächst auf eine halbe Million Zeilen. Es hat eine ziemlich große Reihe (viele Textfelder).

Wir sind searching based of an index, not the primary key (I vergewissert hat, der Index verwendet wird, zumindest unter normalen Bedingungen)

In der Tabelle als persistenten Speicher wird für einen einzelnen Prozess verwendet. Mit PostgresQL unter Windows mit einem Java-Client.

Ich bin bereit, insert and update performance aufgeben die Abfrageleistung zu halten.

Wir betrachten die Anwendung rearchitecting, so dass Daten verteilt auf verschiedene dynamische Tabellen in einer Art und Weise, die uns Indizes fallen lässt und den Wiederaufbau in regelmäßigen Abständen ohne die Anwendung zu beeinträchtigen. Aber wie immer gibt es eine Zeit Crunch diese an der Arbeit und ich vermute, wir etwas Grundsätzliches in unserer Konfiguration oder Nutzung fehlen.

Wir haben forcing vacuuming und rebuild to run at certain times betrachtet, aber ich vermute, die locking period for such an action would cause our query to block. Dies kann eine Option sein, aber es gibt einige in Echtzeit (Fenster von 3-5 Sekunden) Auswirkungen, die andere Veränderungen in unserem Code.

Weitere Informationen: Tabelle und Index

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

Analyse:

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

Und, ja, ich bin mir bewusst, gibt es eine Vielzahl von Dingen we could do to normalize and improve the design of this table ist. Einige dieser Optionen können uns zur Verfügung stehen.

Mein Fokus in dieser Frage ist über Verständnis how PostgresQL is managing the index and query over time (understand why, not just fix). Wenn es getan werden über waren oder erheblich Refactoring, es würde eine Menge Veränderungen sein.

War es hilfreich?

Lösung

Auto Vakuum sollte es tun, vorausgesetzt, Sie konfiguriert es für die gewünschte Leistung.

Weitere Informationen: VACUUM FULL: Das wird Tabellenstatistiken und Rückforderungs Lasten der Speicherplatz wieder aufzubauen. Er sperrt die gesamte Tabelle.

VACUUM: dies wird Tabellenstatistiken neu erstellen und etwas Speicherplatz zurück. Es kann parallel zu Produktionssystem ausgeführt werden, sondern erzeugt eine Menge IO, welche die Leistung auswirken kann.

ANALYSE: Diese Abfrage Planer Statistiken wieder aufbauen. Dies wird durch VACUUM ausgelöst, sondern kann allein ausgeführt werden.

Mehr detaillierte Hinweise finden Sie hier

Andere Tipps

Was die Leistung, Zeit und Status-Info unter Verwendung von Zeichenketten für die Speicherung ist durchaus ein Engpass. Zunächst einmal Indizes für Texte sind äußerst ineffizient, den Vergleich von zwei Mal am selben Tag benötigt mindestens 11 Vergleich (im Format Sie verwendet), aber geben Sie mit der Zeit kann es einfach ein Vergleich reduziert werden. Dies wirkt sich auch auf die Größe des Index, und ein großer Index ist schwer zu suchen über, und der db wird es nicht in Erinnerung behalten. Gleiche Überlegungen gelten für den Staat Spalte. Wenn es eine kleine Gruppe von Staaten darstellt, sollten Sie Integer-Zahlen zu den Zuständen abgebildet verwenden, wird dies die Knoten des Index reduzieren - und die Indexgröße entsprechend. Darüber hinaus wird dieser Index nutzlos sogar theese Typen in integrierten verwenden, wenn Sie nicht die aktuelle Zeit in der Abfrage angeben.

Das riecht nach Index aufblasen zu mir. I'l auf diese Seite verweisen

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

, die am Boden sagt:

  

Auch für B-Tree-Indizes ein   frisch erstellter Index ist etwas   schneller Zugriff als eine, die hat   viele Male aktualisiert, weil   logisch benachbarte Seiten sind in der Regel   auch physikalisch benachbart in einem neu   gebautes Index. (Diese Überlegung tut   gilt derzeit nicht auf Nicht-B-Baum   Indizes.) Es könnte sich lohnen zu   indizieren nur periodisch zu verbessern   Zugriffsgeschwindigkeit.

Die mit der Seite Konflikt scheint Sie referenzierten sagen, dass die Indizes „benötigen keine Wartung oder Tuning“.

Haben Sie versucht, "create index gleichzeitig"?

Ist der '2010-05-20T13: 00: 00.000'? Wert dass xmlscheduledtime zu, einen Teil der SQL verglichen wird, oder als ein Parameter zugeführt

Bei der Planung, wie die Abfrage auszuführen, sagt, dass ein Feld muss kleiner sein als ein Angegebener Parameter mit einem bisher unbekannten Wert nicht geben PostgreSQL viel weiter zu gehen. Er weiß nicht, ob das fast alle Zeilen entsprechen würde, oder kaum eine der Reihen.

Beim Lesen über , wie die Planer verwendet Statistiken enorm hilft, wenn Ihre Datenbank Abbildung versuchen, herauszufinden, warum die Pläne verwendet es ist.

Sie könnten besser wählen Leistung erhalten, indem die Reihenfolge der Felder in diesem komplexen Index ändern oder einen neuen Index zu schaffen, wobei die Felder bestellt (campaignfqname, current, xmlscheduledtime), da dann der Index nehmen Sie direkt in die Kampagne fq Namen und der aktuelle Zustand, dass Sie interessiert sind, und der Index-Scan über die xmlscheduledtime Bereich werden alle Zeilen werden Sie nach.

Das ist ein Lehrbuch. Sie sollten Setup autovacuum viel aggressiver sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top