Einfluss von CLUSTER auf die Leistung


8

Ich versuche, meine Postgres 9.2-Datenbank zu optimieren, um Abfragen mit Datumsbeschränkungen zu beschleunigen.

Ich habe eine timestampSpalte, aber meistens frage ich nach einem Tag, also habe ich einen Index timestampzum dateParsen erstellt:

CREATE INDEX foo_my_timestamp_idx
ON foo
USING btree
((my_timestamp::date) DESC);

Um eine Leistungstabelle zu erhöhen, verwende ich den CLUSTER fooobigen Index:

CLUSTER foo USING foo_my_timestamp_idx;

Laut dem Handbuch zu SQL-CLUSTER ist die Tabelle

wird basierend auf den Indexinformationen physisch neu angeordnet

Ich frage mich, ob sich dies auf die Leistung anderer Abfragen auswirkt, wenn eine PK der Tabelle verwendet wird (sagen wir id_foo). Gibt es Nachteile?

Antworten:


10

Ja, es kann Nachteile geben. Wenn eine andere Abfrage ein anderes Datensegment betrachtet, das nicht durch das Datum bestimmt ist, kann dies zu Leistungseinbußen führen, wenn die Zeilen jetzt auf mehrere Datenseiten verteilt sind. Genauso wie Ihre erste Anfrage profitiert. Das hängt ganz von Informationen ab, die nicht in Ihrer Frage enthalten sind.

andere Abfragen mit einer PK der Tabelle (sagen wir id_foo)

Das könnte alles sein . Es hängt davon ab, was Sie haben und was Sie genau abfragen . Das Abfragen einer einzelnen Zeile ist in keiner Weise betroffen, es können jedoch mehrere Zeilen sein.

Beachten Sie, dass CLUSTERdie Tabelle in makellosem Zustand wie VACUUM FULLfolgt neu geschrieben wird (entfernt tote Tupel, komprimiert die physische Größe der Tabelle, schreibt Indizes neu). Daher können Sie unabhängig von der Sortierreihenfolge einen sofortigen positiven Effekt auf die Leseleistung feststellen. (Ähnlich wie bei VACUUM FULL.)
Anschließend CLUSTERmöchten Sie möglicherweise eine Ebene VACUUMin der Tabelle ausführen , um auch die Sichtbarkeitskarte zu aktualisieren. Dies ermöglicht möglicherweise nur Index-Scans.

Alle Vorteile des CLUSTERSchrumpfens mit der Schreibfrequenz.

Wenn Sie viele Aktualisierungen an der Tabelle haben, CLUSTERkann dies die Schreibleistung beeinträchtigen , indem Sie "Spielraum" für HEISSE Aktualisierungen auf derselben Datenseite entfernen. Möglicherweise können Sie diesem Effekt mit einer FILLFACTOREinstellung unter 100 entgegenwirken. Dies hängt wiederum von der Lokalität der aktualisierten Zeilen usw. ab.

Verbunden:

In jedem Fall würde ich wahrscheinlich nicht indizieren und gruppieren my_timestamp::date, sondern my_timestampdirekt. Nichts verloren, etwas gewonnen. Die Besetzung ist sehr billig, aber es ist immer noch billiger, überhaupt nicht zu besetzen. Und der Index kann mehr Abfragen unterstützen.

CREATE INDEX foo_my_timestamp_idx ON foo (my_timestamp);

Obwohl a datenur 4 Bytes auf der Festplatte und a timestamp8 Bytes belegt, geht der Unterschied in der Regel durch das Ausrichtungs-Padding für Ihren Fall verloren, und beide Indizes haben genau die gleiche Größe.

Die Reihenfolge mehrerer Zeilen am selben Tag, die sich aus Ihrem Ausdrucksindex ergibt, ist beliebig. Es kann immer noch zwei identische Zeitstempel geben, aber mit 6 Bruchstellen ist dies normalerweise sehr unwahrscheinlich. Abgesehen davon erhalten Sie eine deterministische Reihenfolge von Zeilen, die verschiedene Vorteile haben kann.

Ich habe auch das DESCSchlüsselwort fallen lassen, da Postgres Indizes praktisch genauso schnell rückwärts lesen kann wie vorwärts. (Die Sortierreihenfolge ist jedoch für mehrspaltige Indizes von Bedeutung!) Mehr:

Anstatt:

SELECT * FROM foo
WHERE my_timestamp::date = '2016-07-25';

Sie würden jetzt verwenden:

SELECT * FROM foo
WHERE  my_timestamp >= '2016-07-25'  -- this is a timestamp literal now
WHERE  my_timestamp <  '2016-07-26';

Gleiche Leistung.

Wenn Sie die Zeitkomponente der Säule nicht brauchen überhaupt , konvertieren Sie die Spalte date...

Wie rolle ich zurück CLUSTER?

CLUSTERfür eine einzelne Tabelle kann ROLLBACKwie jeder andere reguläre Befehl zurückgesetzt werden, solange die Transaktion nicht festgeschrieben wurde.

Allerdings zitiere ich das Handbuch :

CLUSTEROhne Parameter werden alle zuvor gruppierten Tabellen in der aktuellen Datenbank, die dem aufrufenden Benutzer gehört, oder alle diese Tabellen neu gruppiert, wenn sie von einem Superuser aufgerufen werden. Diese Form von CLUSTERkann nicht innerhalb eines Transaktionsblocks ausgeführt werden.

Sie können immer CLUSTERmit einem anderen Index ausgeführt werden, um die physische Reihenfolge der Zeilen erneut zu ändern.


Ehrfürchtige Antwort, ich muss dann fragen, wie man "zurückrollt" CLUSTER? Muss ich CLUSTERjetzt eine PK verwenden?
Ilovkatie

@ilovkatie: Ich habe ein bisschen hinzugefügt, wie man zurückrollt.
Erwin Brandstetter
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.