2.5 KiB
2.5 KiB
财务仪表盘查询性能分析
结论
默认 7 天首页慢的主要原因不是缺少订单 ID 索引,而是同一时间窗口被重复聚合:每日支付、每日结算、每日预计收入完成后,旧实现又串行执行支付汇总、结算汇总、预计收入汇总。结算聚合还需要按订单关联 order_checkouts 与 wallet_ledger,钱包流水增长后成本随订单数上升。
“先取 ID 再关联详情”适合分页明细,不适合首页 SUM/COUNT。首页已经通过 settled_at 索引先定位订单;把 ID 传到应用层会增加网络传输、IN 参数和内存聚合,不能减少数据库必须扫描的聚合数据。
本次已落地两类优化:
- 每日结果直接派生首页总览,删除三条重复汇总 SQL;支付行同时派生撞车商城总览,费用行同时派生费用总览。
- 财务明细分页先取当前页订单 ID,再限制结账、支付、钱包聚合子查询只处理这些 ID。
- 增加
rental_orders(settlement_mode, offline_settlement_status, offline_settlement_amount_cent)覆盖索引,优化不受日期限制的待线下出款统计。
实测
测试库 hfb_finance_perf 使用 70 天分布的模拟数据:rental_orders 50 万、order_checkouts 50 万、payment_orders 60 万、wallet_ledger 100 万,另有提号、提现和费用数据。
旧实现与新实现返回的完整 Dashboard JSON(去除生成时间)字节级一致;SQL 数量由 31 降至 26。
| 场景 | 总耗时 |
|---|---|
| 旧实现冷查询 | 7.936s |
| 新实现冷查询 | 1.625s |
| 新实现带覆盖索引的一次实测 | 2.894s |
机器负载、缓存和并发会造成波动;服务器低配环境出现 10 秒与上述瓶颈相符。稳定性收益来自减少重复扫描,不能只用一次本机耗时外推生产 P95。
后续治理
- 为所有高频列表记录
duration_ms、扫描行数、P95/P99 和调用接口,按总耗时排序治理。 - 深分页列表逐步从 OFFSET 改为基于
(id, created_at)的游标分页;保留需要跳页的后台列表作为例外。 - 对首页和报表建立按天汇总表(例如
finance_daily_snapshots),业务事件增量更新,首页只读取 7 行快照和少量实时待办。 - 开启 MySQL slow query log 或
performance_schema.events_statements_summary_by_digest,持续检查执行计划是否因数据分布变化回退。 - 对每个复合索引验证过滤列顺序、覆盖列和写入成本;不要为低频或已经低于查询预算的提号小表盲目加索引。