Wie sollen wir mit Zeilen umgehen, die nicht abgefragt werden, wenn sie in PostgreSQL alt sind?

7

Wir haben eine Tabelle in einer PostgreSQL-Datenbank, die in der Größenordnung von Millionen von Zeilen pro Tag wächst.

Jede Zeile besteht aus:

ID
Foreign user ID
Date and time
Other data

Datum und Uhrzeit sind nicht streng monoton ID, sie liegen jedoch nahe beieinander.

Bei der Abfrage dieser Tabelle sind wir nur daran interessiert, Zeilen für eine bestimmte ausländische Benutzer-ID mit Datum und Uhrzeit in den letzten zwei Wochen abzurufen. Zeilen, die älter als zwei Wochen sind, werden niemals abgefragt. Wir möchten sie jedoch zu Archivierungszwecken aufbewahren.

Angesichts dieses speziellen Anwendungsfalls:

  1. Sollten wir einen Index für die Datums- und Zeitspalte haben?
  2. Gibt es einen Hinweis darauf, dass Datum und Uhrzeit mit der ID (fast) monoton zunehmen?
  3. Sollten wir versuchen, Zeilen zu entfernen, die älter als zwei Wochen sind, wird dies wahrscheinlich die Leistung verbessern?
Davetapley
quelle

Antworten:

6
  1. Partitionieren und / oder Teilindizes verwenden, sodass Sie nur einen Index für das Teil haben, das Sie interessiert
  2. Nein, AFAIK, es gibt noch keine Korrelationshinweise in Pg. Das Mitleid.
  3. Hängt stark von der Art der Abfragen ab, aber es kann sich lohnen, dies zu tun, insbesondere wenn Sie dies durch Partitionierung tun können.

Trennwand

Dies ist eine klassische Verwendung für die Tabellenpartitionierung. Partitionieren Sie die Tabelle in zwei (oder mehr) Teile, einen mit den Hot-Daten und einen mit den alten Archivdaten. Indizieren Sie alles, was Sie auf dem Hot Table benötigen, und verwenden Sie weniger Indizes, um Platz und insertZeit auf dem Cold Table zu sparen .

new_tableWenn der Ausschluss von Einschränkungen aktiviert ist, scannt Pg automatisch nur, wenn Ihre Abfragen mit der Partitionierungsbeschränkung übereinstimmen.

Wenn Ihre Abfragen nicht alle dieselbe Einschränkung verwenden, können Sie entweder einen whereTest hinzufügen , der die Einschränkung verwendet, oder die new_tablePartition direkt abfragen .

Teilindizes

Alternativ können Sie Teilindizes erstellen, die nur die Bereiche abdecken, an denen Sie interessiert sind. Auch diese funktionieren nur, wenn Ihre Abfragen Einschränkungen verwenden, die Pg als mit dem Teilindex übereinstimmend erkennen kann. In Ihrem Fall müssten Sie sie im Laufe der Zeit erstellen und löschen, um Ihren Zeitbereich relevant zu halten, da Sie nicht auf einen dynamischen Ausdruck wie indizieren können WHERE (some_field > current_timestamp - INTERVAL '2' week).

Craig Ringer
quelle
4
Ein activeFlag könnte verwendet werden, um einen active = false
Teilindex
2
@a_horse_with_no_name Yep; persönlich würde ich activein diesem Fall nur partitionieren und den Ausschluss von Einschränkungen verwenden, da Sie die Daten sowieso neu schreiben; gleiche Idee und guter Punkt.
Craig Ringer
Vielen Dank für die umfassende Antwort und Ideen. Mehr Karma zu gewinnen bei einer Folgefrage .
Davetapley