如何使用聚合函数改善慢速SQL查询

时间:2019-05-02 14:02:44

标签: sql sql-server

我想显示在本会计年度中注册客户的前十名客户,销售,利润率。该查询大约需要65秒才能运行,并且不被接受:-( 如您所见,我不擅长sql,并且非常乐意提供改进查询的帮助。

SELECT Top 10 
  AcTr.R3, Actor.Nm, 
  SUM(CASE WHEN AcTr.AcNo<='3999' THEN AcAm*-1 ELSE 0 END) AS Sales , 
  SUM(AcAm*-1) AS TB
FROM AcTr, Actor 
WHERE (Actor.CustNo = AcTr.R3) AND
      (Actor.CustNo <> '0') AND
      (Actor.CreDt >= '20180901') AND 
      (Actor.CreDt <= '20190430') AND 
      AcTr.AcYr = '2018' AND
      AcTr.AcPr <= '8' AND
      AcTr.AcNo>='3000' AND
      AcTr.AcNo <= '4999'
GROUP BY AcTr.R3, Actor.Nm 
ORDER BY Sales DESC

1 个答案:

答案 0 :(得分:0)

欢迎来到社区。您有一个良好的开端,但将来,如果您可以提供(如评论所示)CREATE表声明,以便用户知道实际的数据类型,则它将更有帮助。并非总是必需的,但有帮助。

对于您的查询布局,更常见的是显示JOIN语法而不是在其中显示表之间的关系,但这是及时而实际的。

索引有帮助,并且应该基于WHERE / JOIN标准和分组字段的组合。另外,如果字段是数字,则不要“引用”它们,而应保留为数字。例如,您的AcYr,AcPr,AcNo。我认为,出于会计目的,帐号确实是一个字符串值与数字。

我建议您在表上使用以下索引

Table   Index
Actr    ( AcYr, AcPr, AcNo, R3 )
Actor   ( CustNo, CreDt )

Actr表我首先具有过滤条件,最后具有R3以帮助优化GROUP BY。按客户编号的Actor表,然后按CreDt(创建日期?),它实际上是一个字符串,还是日期字段?如果是这样,日期条件将类似于“ 2018-09-01”和“ 2019-04-30”

select TOP 10
        Actor.Nm,
        PreSum.Sales,
        PreSm.TB
    from
        ( select
                R3,
                SUM(CASE WHEN AcTr.AcNo <= '3999' 
                    THEN AcAm * -1 ELSE 0 END) AS Sales,
                SUM( AcAm * -1) AS TB
            from
                Actr
            where
                    AcTr.AcYr = 2018
                AND AcTr.AcPr <= 8
                AND AcTr.AcNo >= '3000' 
                AND AcTr.AcNo <= '4999'
            GROUP BY 
                AcTr.R3 ) PreSum
            JOIN Actor
                on PreSum.R3 = Actor.CustNo
                AND Actor.CustNo <> 0
                AND Actor.CreDt >= '20180901'
                AND Actor.CreDt <= '20190430'
    order by
        Sales DESC