CLUSTER
Wenn Sie beabsichtigen, CLUSTER
zu verwenden , ist die angezeigte Syntax ungültig.
create CLUSTER ticket USING ticket_1_idx;
Einmal ausführen:
CLUSTER ticket USING ticket_1_idx;
Das kann helfen viel mit größeren Ergebnismengen. Nicht so sehr für eine einzelne zurückgegebene Zeile.
Postgres merkt sich, welcher Index für nachfolgende Aufrufe verwendet werden soll. Wenn Ihre Tabelle nicht schreibgeschützt ist, verschlechtert sich der Effekt mit der Zeit und Sie müssen sie in bestimmten Abständen erneut ausführen:
CLUSTER ticket;
Möglicherweise nur auf flüchtigen Partitionen. Siehe unten.
Allerdings , wenn Sie viele Updates haben, CLUSTER
(oder VACUUM FULL
) kann tatsächlich schlecht für die Leistung sein. Die richtige Menge an Aufblähung erlaubt UPDATE
neue Zeilenversionen auf derselben Datenseite zu platzieren und vermeidet die Notwendigkeit, die zugrunde liegende Datei im Betriebssystem zu oft physisch zu erweitern. Sie können einen sorgfältig abgestimmten FILLFACTOR
verwenden um das Beste aus beiden Welten zu bekommen:
- Füllfaktor für einen sequentiellen Index, der PK ist
pg_repack
CLUSTER
nimmt eine exklusive Sperre für die Tabelle, was in einer Umgebung mit mehreren Benutzern ein Problem sein kann. Zitat aus dem Handbuch:
Wenn eine Tabelle geclustert wird, ein ACCESS EXCLUSIVE
es wird eine Sperre erworben. Dies verhindert alle anderen Datenbankoperationen (sowohl Lesen als auch Schreiben ) von der Bearbeitung der Tabelle bis zum CLUSTER
ist fertig.
Fette Hervorhebung von mir. Betrachten Sie die Alternative pg_repack
:
Im Gegensatz zu CLUSTER
und VACUUM FULL
es funktioniert online, ohne während der Verarbeitung eine exklusive Sperre für die verarbeiteten Tabellen zu halten. pg_repack lässt sich effizient booten, mit einer Leistung, die mit der Verwendung von CLUSTER
vergleichbar ist direkt.
und:
pg_repack muss am Ende der Reorganisation eine exklusive Sperre setzen.
Version 1.3.1 funktioniert mit:
PostgreSQL 8.3, 8.4, 9.0, 9.1, 9.2, 9.3, 9.4
Version 1.4.2 funktioniert mit:
PostgreSQL 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 10
Abfrage
Die Abfrage ist einfach genug, um per se keine Performance-Probleme zu verursachen.
Aber ein Wort zur Korrektheit :Der BETWEEN
includes konstruieren Grenzen. Ihre Abfrage wählt den gesamten 19. Dezember plus aus Aufzeichnungen vom 20. Dezember, 00:00 Uhr. Das ist extrem unwahrscheinlich Erfordernis. Die Chancen stehen gut, dass Sie wirklich wollen:
SELECT *
FROM ticket
WHERE created >= '2012-12-19 0:0'
AND created < '2012-12-20 0:0';
Leistung
Zuerst fragen Sie:
Warum wird sequentielles Scannen ausgewählt?
Ihr EXPLAIN
Ausgabe zeigt deutlich einen Index Scan , kein sequentieller Tabellenscan. Da muss ein Missverständnis vorliegen.
Wenn Sie unter Druck gesetzt werden, bessere Leistungen zu erbringen, können Sie möglicherweise Dinge verbessern. Aber die nötigen Hintergrundinformationen kommen nicht in Frage. Mögliche Optionen sind:
-
Sie könnten statt
*
nur erforderliche Spalten abfragen um die Übertragungskosten (und möglicherweise andere Leistungsvorteile) zu reduzieren. -
Sie könnten sich Partitionierung ansehen und legen Sie praktische Zeitscheiben in separaten Tabellen ab. Fügen Sie nach Bedarf Indizes zu Partitionen hinzu.
-
Wenn die Partitionierung keine Option ist, wäre eine andere verwandte, aber weniger aufdringliche Technik, einen oder mehrere partielle Indizes hinzuzufügen .
Zum Beispiel, wenn Sie hauptsächlich den aktuellen Monat abfragen , könnten Sie den folgenden Teilindex erstellen:CREATE INDEX ticket_created_idx ON ticket(created) WHERE created >= '2012-12-01 00:00:00'::timestamp;
CREATE
ein neuer Index direkt vor Beginn eines neuen Monats. Sie können die Aufgabe einfach mit einem Cron-Job automatisieren. OptionalDROP
Teilindizes für alte Monate später. -
Behalten Sie zusätzlich den Gesamtindex für
CLUSTER
bei (die nicht mit Teilindizes arbeiten kann). Wenn sich alte Datensätze nie ändern, würde die Tabellenpartitionierung bei dieser Aufgabe sehr hilfreich sein, da Sie nur neuere Partitionen neu gruppieren müssen. Andererseits, wenn sich Datensätze überhaupt nie ändern, brauchen Sie wahrscheinlichCLUSTER
nicht .
Wenn Sie die letzten beiden Schritte kombinieren, sollte die Leistung fantastisch sein.
Leistungsgrundlagen
Möglicherweise fehlt Ihnen eine der Grundlagen. Es gelten alle üblichen Leistungshinweise:
- https://wiki.postgresql.org/wiki/Slow_Query_Questions
- https://wiki.postgresql.org/wiki/Performance_Optimization