如何优化SQL避免多次JOIN以获取各产品10天的销售数据
SQL优化方案
你当前多次左连接ORDERS_SUMMARY表的写法,会对该表产生多次扫描,数据量较大时性能损耗非常明显,更推荐使用条件聚合的方案实现,仅需扫描一次订单汇总表即可拿到全部10天的销售数据。
优化后SQL示例
SELECT P.ID, P.SKU, -- 第1天数据,时间戳对应你原SQL的1633158000000 MAX(CASE WHEN OS.ORDER_DATE = TO_TIMESTAMP(1633158000000 / 1000.0) THEN OS.AMOUNT END) AS ITEMS_1, MAX(CASE WHEN OS.ORDER_DATE = TO_TIMESTAMP(1633158000000 / 1000.0) THEN ARRAY_LENGTH(OS.LIST, 1) END) AS ORDERS_1, -- 第2天数据,时间戳对应你原SQL的1633676400000 MAX(CASE WHEN OS.ORDER_DATE = TO_TIMESTAMP(1633676400000 / 1000.0) THEN OS.AMOUNT END) AS ITEMS_2, MAX(CASE WHEN OS.ORDER_DATE = TO_TIMESTAMP(1633676400000 / 1000.0) THEN ARRAY_LENGTH(OS.LIST, 1) END) AS ORDERS_2, -- 剩余8天按同样格式补充即可 ... FROM PRODUCTS AS P LEFT JOIN ORDERS_SUMMARY AS OS ON P.SKU = OS.SKU -- 先过滤出仅需要的10天数据,减少聚合计算量 AND OS.ORDER_DATE IN ( TO_TIMESTAMP(1633158000000 / 1000.0), TO_TIMESTAMP(1633676400000 / 1000.0) -- 补充剩余8天的时间戳转换结果即可 ... ) GROUP BY P.ID, P.SKU
方案优势
- 仅扫描1次
ORDERS_SUMMARY表,IO开销远低于多次关联的写法,查询性能提升明显 - 代码结构更简洁,后续新增统计日期仅需补充对应查询列和IN条件里的日期,无需新增整段关联逻辑,维护成本更低
- 避免了多次关联可能带来的意外笛卡尔积风险,稳定性更高
如果你的统计日期是固定周期(比如最近10天),还可以将IN条件里的日期改为动态计算逻辑,无需硬编码时间戳,灵活性更强。
内容的提问来源于stack exchange,提问作者Mj Ebrahimzadeh
相关产品推荐
相关产品推荐

