PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Indiziertes ORDER BY mit LIMIT 1

Angenommen, wir haben es mit einer großen Tabelle zu tun , ein Teilindex könnte helfen:

CREATE INDEX tbl_created_recently_idx ON tbl (created_at DESC)
WHERE created_at > '2013-09-15 0:0'::timestamp;

Wie Sie bereits festgestellt haben:Absteigend oder aufsteigend spielt hier kaum eine Rolle. Postgres kann mit fast der gleichen Geschwindigkeit rückwärts scannen (Ausnahmen gelten bei mehrspaltigen Indizes).

Abfrage, um diesen Index zu verwenden:

SELECT * FROM tbl
WHERE  created_at > '2013-09-15 0:0'::timestamp -- matches index
ORDER  BY created_at DESC
LIMIT  1;

Der Punkt hier ist, den Index viel kleiner zu machen , daher sollte es einfacher zu cachen und zu warten sein.

  1. Sie müssen einen Zeitstempel auswählen, der garantiert kleiner als der aktuellste ist.
  2. Sie sollten den Index von Zeit zu Zeit neu erstellen, um alte Daten abzuschneiden.
  3. Die Bedingung muss IMMUTABLE sein .

Der Einmaleffekt verschlechtert sich also mit der Zeit. Das spezifische Problem ist die fest codierte Bedingung:

WHERE created_at > '2013-09-15 0:0'::timestamp

Automatisieren

Sie könnten den Index und Ihre Abfragen von Zeit zu Zeit manuell aktualisieren. Oder Sie automatisieren es mit Hilfe einer Funktion wie dieser:

CREATE OR REPLACE FUNCTION f_min_ts()
  RETURNS timestamp LANGUAGE sql IMMUTABLE AS
$$SELECT '2013-09-15 0:0'::timestamp$$

Inhaltsverzeichnis:

CREATE INDEX tbl_created_recently_idx ON tbl (created_at DESC);
WHERE created_at > f_min_ts();

Abfrage:

SELECT * FROM tbl
WHERE  created_at > f_min_ts()
ORDER  BY created_at DESC
LIMIT  1;

Automatisieren Sie die Wiederherstellung mit einem Cron-Job oder einem Trigger-basierten Ereignis. Ihre Abfragen können jetzt gleich bleiben. Aber Sie müssen alle Indizes neu erstellen Verwenden Sie diese Funktion in keiner Weise, nachdem Sie sie geändert haben. Legen Sie sie einfach ab und erstellen Sie sie.

Zuerst ..

... testen Sie, ob Sie damit tatsächlich den Flaschenhals treffen.

Versuchen Sie, ob ein einfacher DROP index ... ; CREATE index ... macht den Job. Dann könnte Ihr Index aufgebläht worden sein. Ihre Autovacuum-Einstellungen sind möglicherweise deaktiviert.

Oder versuchen Sie VACUUM FULL ANALYZE um Ihre gesamte Tabelle plus Indizes in makellosem Zustand zu erhalten und erneut zu überprüfen.

Weitere Optionen enthalten die übliche allgemeine Leistungsoptimierung und abdeckende Indizes, je nachdem, was Sie tatsächlich aus der Tabelle abrufen.