You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化含重复条件子查询的SQL调研数据报表?

优化SQL查询:产品评价占比报表

核心优化方案

原方案多次重复扫描Opinions表,导致性能随数据量增长急剧下降。改用一次聚合+关联的方式,既能大幅提升性能,又能简化后续维护:

SELECT
    p.Name,
    -- 处理无评价产品的除数为0问题
    CASE WHEN op.TotalOpinions = 0 THEN 0.0 ELSE 1.0 * op.EasyToUseCount / op.TotalOpinions END AS EasyToUse,
    CASE WHEN op.TotalOpinions = 0 THEN 0.0 ELSE 1.0 * op.GoodPriceCount / op.TotalOpinions END AS GoodPrice,
    CASE WHEN op.TotalOpinions = 0 THEN 0.0 ELSE 1.0 * op.DurableCount / op.TotalOpinions END AS Durable
FROM Products p
LEFT JOIN (
    SELECT
        ProductId,
        COUNT(*) AS TotalOpinions,
        SUM(CAST(IsEasyToUse AS INT)) AS EasyToUseCount,
        SUM(CAST(IsGoodPrice AS INT)) AS GoodPriceCount,
        SUM(CAST(IsDurable AS INT)) AS DurableCount
    FROM Opinions
    GROUP BY ProductId
) op ON p.Id = op.ProductId

优化说明

  1. 性能提升:仅扫描一次Opinions表,通过GROUP BY ProductId完成所有统计计算,避免原方案中每个评价维度执行两次子查询(多次重复扫描数据),100万行数据场景下耗时会大幅降低。
  2. 简化维护:后续新增评价字段(如IsRecommend),只需在子查询中添加一行SUM(CAST(IsRecommend AS INT)) AS RecommendCount,再在主查询中补充对应占比计算即可,无需重复编写子查询逻辑。
  3. 异常处理:通过CASE语句处理无评价产品的除数为0问题,避免查询报错,同时保证报表完整性(无评价产品占比显示为0)。
  4. 索引优化建议:给Opinions表创建包含统计字段的非聚集索引,进一步加速聚合查询:
CREATE NONCLUSTERED INDEX IX_Opinions_ProductId 
ON Opinions(ProductId) 
INCLUDE(IsEasyToUse, IsGoodPrice, IsDurable)

该索引让数据库无需扫描整张表,直接从索引中获取所需统计数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 19:22:28