Sie können jederzeit eine eigene Tabelle implementieren, die als "materialisierte Ansicht" dient. Das mussten Sie tun, bevor MATERIALIZED VIEWPostgres 9.3 so oder so implementiert wurde.
Beispielsweise können Sie eine Ebene erstellen VIEW:
CREATE VIEW graph_avg_view AS
SELECT xaxis, AVG(value) AS avg_val
FROM graph
GROUP BY xaxis;
Und materialisieren Sie das Ergebnis als Ganzes einmal oder wann immer Sie von vorne anfangen müssen:
CREATE TABLE graph_avg AS
SELECT * FROM graph_avg_view
(Oder die Verwendung SELECTAnweisung direkt, ohne ein zu schaffen VIEW.)
Dann, abhängig von undisclosed Details Ihrer Verwendung Fall, könnten Sie DELETE/ UPDATE/ INSERTÄnderungen manuell.
Eine grundlegende DML-Anweisung mit datenmodifizierenden CTEs für Ihre Tabelle wie folgt :
Unter der Annahme , sonst niemand versucht zu schreiben , um graph_avggleichzeitig (Lesen ist kein Problem):
WITH del AS (
DELETE FROM graph_avg t
WHERE NOT EXISTS (SELECT 1 FROM graph_avg_view v WHERE v.xaxis = v.xaxis);
)
, upd AS (
UPDATE graph_avg t
FROM graph_avg_view v
WHERE t.xaxis = v.xaxis
AND t.avg_val <> v.avg_val
)
INSERT INTO graph_avg t
SELECT *
FROM graph_avg_view v
LEFT JOIN graph_avg t USING (xaxis)
WHERE t.xaxis IS NULL;
Dies sollte aber höchstwahrscheinlich optimiert werden.
Grundrezept:
- Fügen Sie Ihrer Basistabelle eine
timestampStandardspalte hinzu now(). Nennen wir es ts.
- Wenn Sie Aktualisierungen haben, fügen Sie einen Auslöser hinzu, um den aktuellen Zeitstempel für jede Aktualisierung festzulegen, die entweder
xaxisoder geändert wird value.
Erstellen Sie eine winzige Tabelle, um sich den Zeitstempel Ihres letzten Schnappschusses zu merken. Nennen wir es mv:
CREATE TABLE mv (
tbl text PRIMARY KEY
, ts timestamp NOT NULL DEFAULT '-infinity'
); -- possibly more details
Erstellen Sie diesen mehrspaltigen Teilindex:
CREATE INDEX graph_mv_latest ON graph (xaxis, value)
WHERE ts >= '-infinity';
Verwenden Sie den Zeitstempel des letzten Snapshots als Vergleichselement in Ihren Abfragen, um den Snapshot mit perfekter Indexnutzung zu aktualisieren.
Löschen Sie am Ende der Transaktion den Index und erstellen Sie ihn neu, wobei der Transaktionszeitstempel den Zeitstempel im Indexprädikat (anfangs '-infinity') ersetzt, den Sie auch in Ihrer Tabelle speichern. Alles in einer Transaktion.
Beachten Sie, dass der Teilindex Abdeckung ist groß INSERTund UPDATEOperationen, aber nicht DELETE. Um dies abzudecken, müssen Sie die gesamte Tabelle betrachten. Alles hängt von den genauen Anforderungen ab.