항상 "구체화 된 뷰"로 제공되는 자체 테이블을 구현할 수 있습니다. 그것은 당신이 MATERIALIZED VIEW
Postgres 9.3에서 어느 쪽이든 구현 하기 전에해야했던 것입니다.
예를 들어 일반을 만들 수 있습니다 VIEW
.
CREATE VIEW graph_avg_view AS
SELECT xaxis, AVG(value) AS avg_val
FROM graph
GROUP BY xaxis;
그리고 결과를 한 번 또는 다시 시작해야 할 때마다 구체화하십시오.
CREATE TABLE graph_avg AS
SELECT * FROM graph_avg_view
(또는 SELECT
문을 직접 작성하지 않고 문을 사용하십시오 VIEW
.)
그런 다음 유스 케이스의 공개되지 않은 세부 사항에 따라 수동으로 DELETE
/ UPDATE
/ INSERT
변경할 수 있습니다.
테이블에 대한 데이터 수정 CTE가있는 기본 DML 문 은 다음 과 같습니다.
다른 사람 이 동시에 쓰려고graph_avg
하지 않는다고 가정하면 (읽기는 문제가되지 않습니다) :
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;
그러나 이것은 아마도 최적화되어야합니다.
기본 레시피 :
- 기본 테이블
timestamp
을 기본값 now()
으로 열을 추가하십시오 . 그것을 호출하자 ts
.
- 업데이트를하는 경우 중 하나를 변경 때마다 업데이트로 현재 타임 스탬프 설정하는 트리거를 추가
xaxis
또는 value
.
작은 테이블을 만들어 최신 스냅 샷의 타임 스탬프를 기억하십시오. 전화합시다 mv
:
CREATE TABLE mv (
tbl text PRIMARY KEY
, ts timestamp NOT NULL DEFAULT '-infinity'
); -- possibly more details
이 부분 다중 열 색인을 작성하십시오.
CREATE INDEX graph_mv_latest ON graph (xaxis, value)
WHERE ts >= '-infinity';
쿼리에서 조건부로 마지막 스냅 샷 의 타임 스탬프를 사용하여 완벽한 인덱스 사용법으로 스냅 샷을 새로 고칩니다.
트랜잭션이 끝날 때 인덱스를 삭제하고 인덱스 술어 (초기 '-infinity'
) 의 타임 스탬프를 테이블에 저장 한 트랜잭션 타임 스탬프로 다시 작성하십시오 . 한 번의 거래로 모든 것 .
참고 부분 인덱스가 커버에 큰 것을 INSERT
및 UPDATE
운영 있지만 DELETE
. 이를 다루려면 전체 테이블을 고려해야합니다. 그것은 모두 정확한 요구 사항에 달려 있습니다.