Sie können jederzeit eine eigene Tabelle implementieren, die als "materialisierte Ansicht" dient. Das mussten Sie tun, bevor MATERIALIZED VIEW
Postgres 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 SELECT
Anweisung 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_avg
gleichzeitig (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
timestamp
Standardspalte 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
xaxis
oder 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ß INSERT
und UPDATE
Operationen, aber nicht DELETE
. Um dies abzudecken, müssen Sie die gesamte Tabelle betrachten. Alles hängt von den genauen Anforderungen ab.