视图中GROUP BY后JOIN更慢,因视图不存数据,每次查询需先全量JOIN再聚合,导致中间结果膨胀(如500万行),而外层WHERE无法下推至聚合前过滤,造成大量无效计算。
因为视图不存数据,每次查询都会完整展开底层 SQL。如果视图定义是 SELECT u.name, SUM(o.amount) FROM users u JOIN orders o ON u.id = o.user_id GROUP BY u.id,数据库必须先把所有用户和订单的匹配组合全算出来(比如 10 万用户 × 平均 50 订单 = 500 万行中间结果),再分组——而你最终只想要最近 7 天的数据,这 500 万行里 99% 是白算的。
典型错误是:在 CDS 视图或 SQL 视图里先用 GROUP BY 聚出一个“用户总消费”列,再拿这个列去和其他表 JOIN。问题在于,聚合本身不改变关联键的语义,但数据库优化器往往无法把外层 WHERE 条件下推到聚合前过滤,导致先膨胀、再过滤。
user_id 和 total_amount,外部查询加了 WHERE created_at > '2026-06-01',但该条件根本进不到 orders 表扫描阶段collect_list()、median())还可能保留全量中间数据,进一步加剧内存压力直接看执行计划里的 rows 预估值:如果 JOIN 后的行数远大于最终结果行数(比如预估 287641 行,GROUP BY 后只剩 321 行),基本可以断定是路径设计问题。
EXPLAIN 或 SET STATISTICS XML ON 查看实际驱动表和中间行数估算Hash Match Aggregate 前跟着巨大的 Nested Loop 或 Table Scan
WHERE 过滤再跑一次——如果快很多,说明问题出在视图展开逻辑,而非数据或索引性能瓶颈从来不在聚合函数本身,而在数据还没变少就急着连。你得让数据在进入 JOIN 前就压缩到最小粒度。
SELECT user_id, SUM(amount) FROM orders WHERE created_at >= '2026-06-01' GROUP BY user_id,再和 users 关联orders_7d_summary),比每次重算稳定得多CREATE TEMPORARY TABLE tmp_orders_agg AS ...,再 ALTER TABLE ... ADD INDEX,注意字段类型显式对齐(比如 user_id 是 BIGINT,别让它隐式转成 INT)最容易被忽略的一点:索引对这种膨胀几乎无效——你不是在给最终结果加速,而是在给百万行中间结果排序。先让数据变少,再让它连得快。