单查询实现特定日期各门店小时级销售报表优化方案问询
解决方案:单条分组查询实现多门店小时级统计
当然可以!你现在碰到的问题核心是多次循环查询导致数据库重复计算、连接开销过大,用单条分组查询就能彻底解决这个问题,一次性返回所有门店各小时的统计结果,大幅降低数据库负载。
优化后的单条查询语句
针对你的场景,我们可以通过提取时间的小时段,再按「门店ID + 小时段」分组来实现统计:
SELECT invoice_branch_id AS branchId, DATE_FORMAT(invoice_created_date, '%Y-%m-%d %H:00:00') AS hourSegment, SUM(total_payble) AS totalPayble, SUM(invoice_pax_no) AS totalPax, COUNT(invoice_id) AS totalInvoice FROM bkt_invoice WHERE invoice_created_date BETWEEN '2016-09-20 00:00:00' AND '2016-09-20 23:59:59' AND invoice_is_void = 0 GROUP BY invoice_branch_id, hourSegment ORDER BY invoice_branch_id, hourSegment;
关键逻辑说明
- 提取小时段:用
DATE_FORMAT把invoice_created_date格式化为「年月日 小时:00:00」的形式,这样同一小时内的所有记录会被归为同一个时间分段 - 分组统计:通过
GROUP BY invoice_branch_id, hourSegment,让数据库自动按门店和小时段分别计算总和、计数,完全不需要你循环发起多次请求 - 过滤条件:保留原有的
invoice_is_void = 0(排除作废发票),同时把日期范围扩大到单日全时段,不用再拆成每个小时的独立区间
额外性能优化建议
为了让这个查询跑得更快,建议给bkt_invoice表创建联合索引:
CREATE INDEX idx_invoice_branch_date_void ON bkt_invoice (invoice_branch_id, invoice_created_date, invoice_is_void);
这个索引会覆盖查询中的过滤、分组字段,避免数据库全表扫描,进一步降低服务器负载。
内容的提问来源于stack exchange,提问作者Architect - Hitesh
相关产品推荐
相关产品推荐

