← 中文资源

简体中文版本

物化视图

物化视图把查询结果物理存储下来,以新鲜度和写入成本换取昂贵聚合或连接查询的快速读取。

阅读英文原文

存储昂贵结果

仪表盘查询可能连接五张表并聚合数百万行。每次页面加载都执行它是浪费。物化视图计算一次并存储结果,读取变成对已存行的简单扫描。

CREATE MATERIALIZED VIEW daily_revenue AS
SELECT date_trunc('day', created_at) AS day,
       sum(total_cents) AS revenue,
       count(*) AS orders
FROM orders
GROUP BY 1;

CREATE UNIQUE INDEX daily_revenue_day_idx ON daily_revenue (day);

REFRESH MATERIALIZED VIEW CONCURRENTLY daily_revenue;

CONCURRENTLY 需要唯一索引,刷新时不阻塞读取,代价是更多工作。普通刷新会加排他锁并阻塞读取。应根据读取可用性要求和结果大小选择。

新鲜度是产品决策

每个物化视图都有陈旧窗口。UI 应显示数据时间戳,并定义可接受的新鲜度。日报可以旧一天,反欺诈仪表盘不行。近实时需求应使用增量物化、变更数据捕获或流式聚合,而不是全量刷新。

刷新成本随结果大小和查询复杂度增长。把刷新安排在低谷,监控时长和锁等待,并避免比底层数据变化更频繁地刷新。每小时变化一次的表每分钟刷新一次是浪费。

给结果建索引

物化视图是物理表,需要为读取它的查询建索引。在过滤和连接列上添加索引,并在刷新后分析视图,让优化器有统计信息。没有统计信息的物化视图可能产生比原查询更差的计划。

何时使用

当复杂读取频繁、基础数据变化较慢,并且可以接受有界陈旧时,使用物化视图。优点是快速可预测的读取;缺点是存储、刷新成本和陈旧数据。与应用缓存相比,它位于数据库内,可索引、可连接,并由数据库刷新,而不是由应用失效逻辑维护。