Você sempre pode implementar sua própria tabela, servindo como "visualização materializada". Isso é o que você tinha que fazer antes de MATERIALIZED VIEW
ser implementado no Postgres 9.3 de qualquer maneira.
Por exemplo, você pode criar uma planície VIEW
:
CREATE VIEW graph_avg_view AS
SELECT xaxis, AVG(value) AS avg_val
FROM graph
GROUP BY xaxis;
E materialize o resultado como um todo uma vez ou sempre que precisar começar de novo:
CREATE TABLE graph_avg AS
SELECT * FROM graph_avg_view
(Ou use a SELECT
instrução diretamente, sem criar a VIEW
.)
Então, dependendo dos detalhes não revelados do seu caso de uso, você pode DELETE
/ UPDATE
/ INSERT
alterar manualmente.
Uma instrução DML básica com CTEs modificadores de dados para sua tabela, como é :
Assumindo Ninguém tenta outra pessoa para escrever a graph_avg
concorrentemente (leitura não é problema):
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;
Mas isso provavelmente deve ser otimizado.
Receita básica:
- Adicione uma
timestamp
coluna com padrão now()
à sua tabela base. Vamos chamá-lo ts
.
- Se você tiver atualizações, adicione um gatilho para definir o carimbo de data / hora atual a cada atualização que seja alterada
xaxis
ou value
.
Crie uma pequena tabela para lembrar o carimbo de data e hora do seu instantâneo mais recente. Vamos chamá-lo mv
:
CREATE TABLE mv (
tbl text PRIMARY KEY
, ts timestamp NOT NULL DEFAULT '-infinity'
); -- possibly more details
Crie este índice parcial, com várias colunas:
CREATE INDEX graph_mv_latest ON graph (xaxis, value)
WHERE ts >= '-infinity';
Use o registro de data e hora do último instantâneo como predicado em suas consultas para atualizar o instantâneo com o uso perfeito do índice.
No final da transação, descarte o índice e recrie-o com o registro de data e hora da transação, substituindo o registro de data e hora no predicado do índice (inicialmente '-infinity'
), que você também salva na sua tabela. Tudo em uma transação.
Observe que o índice parcial é ótimo para cobrir INSERT
e UPDATE
operações, mas não DELETE
. Para cobrir isso, você precisa considerar a tabela inteira. Tudo depende dos requisitos exatos.