为什么你的大数据可视化总是“卡成PPT”?聊聊预聚合、物化视图与缓存策略,性能提升10倍其实并不难!

举报
Echo_Wish 发表于 2026/06/28 17:31:26 2026/06/28
【摘要】 为什么你的大数据可视化总是“卡成PPT”?聊聊预聚合、物化视图与缓存策略,性能提升10倍其实并不难!

为什么你的大数据可视化总是“卡成PPT”?聊聊预聚合、物化视图与缓存策略,性能提升10倍其实并不难!

作者:Echo_Wish

很多人做大数据平台的时候,都有一个共同的梦想:

数据实时、图表丝滑、领导满意。

可现实却是另一番景象。

业务同事上午十点打开 BI 看板,页面一直转圈。

运营说:“是不是数据库挂了?”

开发说:“数据库CPU才20%,没问题。”

DBA说:“SQL执行也就5秒。”

最后发现——真正耗时的是几十个复杂SQL、几十亿数据扫描、几十个维度Join,以及一个页面同时请求二十多个图表。

于是,一个价值几百万的大数据平台,活生生被做成了PowerPoint。

很多人第一反应就是:

  • 加机器
  • 扩容集群
  • 提升CPU
  • 上更贵的数据库

但我想说一句很多人可能不太愿意接受的话:

绝大多数可视化性能问题,不是硬件问题,而是架构问题。

真正优秀的大数据可视化系统,几乎都会围绕三个关键词展开:

预聚合(Pre-Aggregation) + 物化视图(Materialized View) + 缓存(Cache)

今天,我们就聊聊这三个"性能神器"。


为什么BI看板越来越慢?

很多项目的数据流都是这样的:

用户打开页面
        │
        ▼
前端请求API
        │
        ▼
后台执行SQL
        │
        ▼
扫描TB级数据
        │
        ▼
GROUP BY
JOIN
ORDER BY
COUNT
SUM
AVG
……
        │
        ▼
返回结果

如果每天几千万数据还好。

如果一年几十亿数据呢?

例如这样一个SQL:

SELECT
    province,
    product_type,
    SUM(order_amount) total_amount
FROM fact_order
WHERE order_time >= '2026-01-01'
GROUP BY province,product_type;

数据量:

fact_order

120亿条

意味着什么?

每刷新一次页面:

扫描120亿记录

领导点一下刷新:

再扫120亿。

十个领导一起看:

1200亿。

数据库:

“你礼貌吗?”


第一把利器:预聚合(Pre-Aggregation)

很多指标,其实每天都一样。

例如:

今日销售额

今日订单数

今日用户数

地区销量

商品销量

这些数据没有必要每次都重新统计。

正确做法:

每天提前计算。

例如:

凌晨1ETL开始

统计:

江苏

今天销售额

800

浙江:

650

广东:

1200

直接写入:

ads_sale_day

数据表:

日期
地区
销售额
订单数
退款数

那么查询变成:

SELECT *
FROM ads_sale_day;

原来:

扫描120亿

现在:

扫描31

这就是预聚合。

一句话:

把计算时间放到后台,把查询时间留给用户。


Spark中如何做预聚合?

例如:

from pyspark.sql import SparkSession
from pyspark.sql.functions import sum

spark = SparkSession.builder.appName("PreAggregation").getOrCreate()

df = spark.read.parquet("/warehouse/fact_order")

result = (
    df.groupBy("province", "order_date")
      .agg(sum("order_amount").alias("total_amount"))
)

result.write.mode("overwrite").saveAsTable("ads_sale_day")

每天凌晨跑一次即可。

真正查询的时候:

直接查ADS

而不是ODS。

这也是为什么数据仓库会有:

ODSDWDDWSADS

ADS存在的意义:

就是给BI准备好的。


第二把利器:物化视图(Materialized View)

很多人知道:

VIEW

其实:

VIEW

并不会保存数据。

例如:

CREATE VIEW order_view AS
SELECT
province,
SUM(order_amount)
FROM fact_order
GROUP BY province;

每查询一次:

都会重新计算。

而物化视图不同。

例如:

CREATE MATERIALIZED VIEW mv_order
AS
SELECT
province,
SUM(order_amount) total_amount
FROM fact_order
GROUP BY province;

第一次:

计算完成

结果直接保存。

以后:

SELECT * FROM mv_order;

不用重新扫描。

真正做到:

秒级返回

ClickHouse中的物化视图

例如:

CREATE MATERIALIZED VIEW mv_sales
ENGINE = SummingMergeTree()
ORDER BY province
AS
SELECT
    province,
    sum(order_amount) AS total_amount
FROM fact_order
GROUP BY province;

以后新增数据:

INSERT

物化视图自动更新。

查询:

SELECT *
FROM mv_sales;

速度通常比原表快几个数量级。


第三把利器:缓存(Cache)

很多BI页面其实都有共同特点。

比如:

每天:

昨天销售额

一天都不会变化。

但是:

1000个人都会查询。

如果:

1000个人

全部查数据库。

数据库:

1000SQL

如果:

第一次查询:

数据库计算。

后面:

全部Redis返回。

流程:

用户

↓

Redis

↓

没有

↓

数据库

↓

Redis

↓

用户

第二次:

Redis

↓

用户

几十毫秒完成。

Python示例:

import redis
import json

r = redis.Redis(host="localhost", port=6379)

key = "dashboard:sales"

data = r.get(key)

if data:
    result = json.loads(data)
else:
    result = query_database()
    r.setex(key, 300, json.dumps(result))

这里只设置了:

300秒缓存

五分钟更新一次。

对于BI来说:

已经非常实时。


缓存不是万能药

很多人喜欢:

所有接口

全部Redis

这是错误的。

缓存适合:

✅ 首页大屏

✅ 看板统计

✅ 排行榜

✅ 热门商品

✅ 用户画像

而:

订单详情

物流状态

支付状态

实时变化的数据:

不适合长时间缓存。

否则:

用户:

我都付款了。

怎么还是未支付?

三种优化方案到底怎么选?

很多团队容易陷入一个误区:认为三种方案只能选一种。

实际上,它们更像是三个不同层次的加速器,而不是竞争关系。

场景 推荐方案 原因
固定日报、周报、月报 预聚合 一次计算,多次查询
高频统计分析 物化视图 自动维护聚合结果,减少重复计算
首页大屏、BI仪表盘 Redis缓存 响应速度最快,用户体验最好
实时数据监控 物化视图 + 短缓存 在实时性与性能之间取得平衡
海量历史分析 预聚合 + 分层建模 避免每次扫描全量历史数据

很多成熟的大数据平台,其实是三者叠加使用,而不是单兵作战。


一个成熟的大数据可视化架构应该是什么样?

真正稳定、高性能的企业级可视化平台,通常都会采用类似下面的架构:

                 数据源
                    │
         Kafka / Flink / ETL
                    │
                    ▼
               ODS 原始层
                    │
                    ▼
               DWD 明细层
                    │
                    ▼
              DWS 汇总层
                    │
        预聚合 / 物化视图
                    │
                    ▼
               ADS 应用层
                    │
          Redis / 本地缓存
                    │
                    ▼
          API 服务(FastAPI、Spring Boot)
                    │
                    ▼
      ECharts / Superset / Power BI

这套架构的核心思想只有一句话:

越靠近用户,数据越轻;越靠近底层,数据越全。

也就是说,把复杂计算尽量放到离线或后台完成,把用户真正访问的数据压缩到最小、最快、最容易获取的状态。


最后想说

这些年接触过不少数据平台项目,我发现一个有趣的现象:很多团队把大量精力投入到数据库选型、集群扩容和硬件升级上,却忽略了数据访问路径本身。

实际上,一个优秀的可视化系统追求的并不是"数据库跑得更快",而是尽量让数据库少跑

预聚合减少重复计算,物化视图降低实时聚合成本,缓存则拦住绝大多数重复请求。三者结合,带来的不仅仅是性能提升,更是系统稳定性、资源利用率和用户体验的全面改善。

大数据平台真正的竞争力,从来不是拥有多少节点、多少TB存储,而是能否让用户在点击图表的一瞬间,就得到想要的答案。

好的可视化,不应该让用户等待;好的架构,也不应该让数据库疲于奔命。

记住一句我一直很认同的话:

性能优化的最高境界,不是把计算做得更快,而是让那些本不该发生的计算,根本不用发生。——这,才是大数据可视化性能优化的真正价值。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。