最近看到 Aurora PostgreSQL 可以直接查询数据湖里的 Iceberg 和 Parquet 数据、省掉一道 ETL 的方案,联想到 K3 系统里报表慢这个老问题,聊聊思路。
问题的本质
K3 的业务库和报表查询天然冲突。业务库要处理大量短事务,要求低延迟和高并发;报表查询要扫大量历史数据,耗时长、占资源。
两者跑在同一个库上时,一个复杂报表可以把整个系统的响应拖慢。这是很多企业遇到的经典困境。
传统解法及其代价
常见做法是建一个独立的数据仓库,通过 ETL 或 CDC 定时同步。
代价有三块:一是同步延迟,报表数据滞后;二是管道维护成本,任务失败了要有人处理;三是一致性问题,两边数据对不上时的排查很痛苦。
另一种思路:查询层不关心数据在哪
像 Aurora 内嵌列式引擎那样,让同一条查询可以同时访问业务表和历史数据文件。这样一部分分析需求可以就地完成,不必先搬数据。
对 K3 环境来说,完整照搬这个架构不现实,但思路可以借鉴:
把历史数据归档到独立的存储,同时在查询层做统一入口,让报表不必关心数据来自业务库还是归档库。
具体可以做的三件事
第一,冷热分离。把超过一定年限的历史单据移出主库。这一步的收益最直接——主库变小,备份变快,索引维护变轻。
第二,为报表建专用只读副本。用数据库原生的复制能力,把读流量摘到副本上,避免影响主库事务。
第三,固化高频报表。对每天都要跑的固定报表,用物化视图或定时任务预计算,把查询变成读结果。
冷热分离的注意事项
判断哪些数据能归档要慎重。财务凭证、未结案单据、有审计要求的记录通常不能移。
归档前跟财务和审计确认保留策略,并且确保归档数据仍然可查——否则等于数据丢失。
归档操作本身要分批做,一次删几百万行会锁表。
一个容易忽略的优化
很多报表慢不是因为数据量大,而是因为写法问题:在 WHERE 子句里对字段做函数运算导致索引失效、用了 SELECT * 然后只取几列、嵌套子查询重复扫描同一张表。
先做执行计划分析,再谈架构改造。很多时候改一条 SQL 比建一套数据仓库划算得多。
优先级建议
先优化 SQL 和索引,再做读写分离,最后考虑冷热分离和数据仓库。按这个顺序,投入产出比递减但必要性递增。
本文由奇幻维度内容助手整理发布,欢迎在评论区交流你的看法。