You need to enable JavaScript to run this app. 如何改写SQL查询提升效率:获取客户两类账户最新交易日期
优惠活动
大模型
产品
解决方案
定价
更多

如何改写SQL查询提升效率:获取客户两类账户最新交易日期

SQL查询优化方案:多表左连聚合性能问题解决

问题根因

你现有写法的核心性能瓶颈是关联后的笛卡尔积膨胀:两个左连接的账户表相互独立,若同一个客户在日常消费账户有N条交易、储蓄账户有M条交易,关联后会生成N*M条中间数据,再做聚合的计算量会指数级上升,这就是查询慢、数据量级异常膨胀的核心原因,和max()函数本身的计算成本无关,不需要刻意规避max()。

优化方案

方案1:先聚合再关联(通用性最强,全SQL环境支持)

先分别对两个账户表按客户ID聚合出最大交易日期,保证每个账户子查询中单个客户仅对应1条记录,再和客户表关联,完全避免笛卡尔积。

select 
    c.client_id,
    e.max_everyday_trans_date,
    s.max_savings_trans_date
from client_table c
left join (
    select client_id, max(transaction_date) as max_everyday_trans_date
    from everyday_account
    group by client_id
) e on c.client_id = e.client_id
left join (
    select client_id, max(transaction_date) as max_savings_trans_date
    from savings_account
    group by client_id
) s on c.client_id = s.client_id

该方案的中间数据量最多为「客户表总条数 + 日常账户去重客户数 + 储蓄账户去重客户数」,对比原有写法的乘积级数据量,性能提升非常明显。

方案2:标量子查询(适合客户表量级不大的场景,写法更简洁)

直接在SELECT子句中通过关联子查询取每个客户的最大交易日期,不需要额外写GROUP BY逻辑:

select 
    c.client_id,
    (select max(transaction_date) from everyday_account e where e.client_id = c.client_id) as max_everyday_trans_date,
    (select max(transaction_date) from savings_account s where s.client_id = c.client_id) as max_savings_trans_date
from client_table c

如果账户表建了合适的联合索引,该写法会走索引覆盖,不需要回表查询,性能表现也很优异。

必要的索引优化

不管用上述哪种方案,都建议加两个联合索引,可以进一步把查询速度提升数倍:

  • 给everyday_account表建联合索引:(client_id, transaction_date)
  • 给savings_account表建联合索引:(client_id, transaction_date)

如果client_table的client_id是主键,本身已经有索引,不需要额外新增。

内容的提问来源于stack exchange,提问作者Serendipity

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 01:36:03