餐饮企业 MySQL 千万级订单查询优化实践

业务背景

随着门店数量突破 2000 家,公司的中央订单库 (orders 表) 数据量单月新增超过 3000万 条。在每月末进行全国大区营业额聚合分析时,商业智能(BI)平台频繁出现超时断连,一条包含 GROUP BY 与多表 JOIN 的复杂报表 SQL 耗时高达 12 秒。

性能瓶颈分析

通过 EXPLAIN 指令,我们定位到核心问题:

  1. 索引失效:查询条件中对 created_at 字段使用了函数 DATE(created_at)
  2. 临时表与文件排序:由于 GROUP BY store_id 并没有命中组合索引,MySQL 在磁盘上创建了庞大的临时表 (Using temporary; Using filesort)。

优化方案落地

1. 消除函数索引依赖

我们将原有代码逻辑:

SELECT store_id, SUM(total_amount) 
FROM orders 
WHERE DATE(created_at) = '2026-05-01'
GROUP BY store_id;

修改为基于范围查询(走 B+ 树索引):

SELECT store_id, SUM(total_amount) 
FROM orders 
WHERE created_at >= '2026-05-01 00:00:00' 
  AND created_at < '2026-05-02 00:00:00'
GROUP BY store_id;

2. 构建黄金组合索引

根据最左前缀匹配原则,我们为该查询创建了联合索引 idx_created_store

ALTER TABLE orders ADD INDEX idx_created_store (created_at, store_id, total_amount);

此举不仅消除了 filesort,同时实现了覆盖索引 (Covering Index),引擎可直接从索引树中读取 total_amount,避免了耗时的回表 (Bookmark Lookup) 操作。

结果收益

优化上线后,全国大区聚合报表的 P99 耗时从 12.4s 骤降至 180ms。报表拉取变得如同丝般顺滑,大幅提升了管理层的决策效率。