Anda selalu dapat menerapkan tabel Anda sendiri yang berfungsi sebagai "tampilan terwujud". Itulah yang harus Anda lakukan sebelum MATERIALIZED VIEW
diterapkan di Postgres 9.3.
Misalnya, Anda dapat membuat polos VIEW
:
CREATE VIEW graph_avg_view AS
SELECT xaxis, AVG(value) AS avg_val
FROM graph
GROUP BY xaxis;
Dan terwujud hasilnya secara keseluruhan sekali atau kapan pun Anda perlu memulai dari awal:
CREATE TABLE graph_avg AS
SELECT * FROM graph_avg_view
(Atau gunakan SELECT
pernyataan secara langsung, tanpa membuat a VIEW
.)
Kemudian, tergantung pada detail yang tidak diketahui dari use case Anda, Anda bisa DELETE
/ UPDATE
/ INSERT
berubah secara manual.
Pernyataan DML dasar dengan CTE pemodifikasi data untuk tabel Anda adalah :
Dengan asumsi tidak ada mencoba lagi untuk menulis untuk graph_avg
secara bersamaan (membaca adalah tidak ada masalah):
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;
Tetapi ini kemungkinan besar harus dioptimalkan.
Resep dasar:
- Tambahkan
timestamp
kolom dengan default now()
ke tabel basis Anda. Sebut saja ts
.
- Jika Anda memiliki pembaruan, tambahkan pemicu untuk mengatur cap waktu saat ini dengan setiap pembaruan yang berubah baik
xaxis
atau value
.
Buat tabel kecil untuk mengingat stempel waktu dari foto terbaru Anda. Sebut saja mv
:
CREATE TABLE mv (
tbl text PRIMARY KEY
, ts timestamp NOT NULL DEFAULT '-infinity'
); -- possibly more details
Buat parsial, indeks multikolom ini:
CREATE INDEX graph_mv_latest ON graph (xaxis, value)
WHERE ts >= '-infinity';
Gunakan cap waktu snapshot terakhir sebagai predikat dalam kueri Anda untuk menyegarkan snapshot dengan penggunaan indeks yang sempurna.
Di akhir transaksi, lepaskan indeks dan buat kembali dengan stempel waktu transaksi menggantikan stempel waktu dalam predikat indeks (awalnya '-infinity'
), yang juga Anda simpan ke meja Anda. Semuanya dalam satu transaksi.
Perhatikan bahwa indeks parsial bagus untuk dibahas INSERT
dan UPDATE
dioperasikan, tetapi tidak DELETE
. Untuk mengatasinya, Anda perlu mempertimbangkan seluruh tabel. Itu semua tergantung pada persyaratan yang tepat.