查询急需优化,但我不知道如何优化它

时间:2011-08-23 21:15:12

标签: sql sql-server

我有以下查询

SELECT
   YEAR(N.TICKETDATE) AS TICKETYEAR,
   MONTH(N.TICKETDATE) AS TICKETMONTH,
   SUM(DISTINCT N.NETWEIGHTHAULED)/COUNT(DISTINCT N.NETWEIGHTHAULED) AS NETTONSHAULED ,
   COUNT(N.TICKETID) AS TICKETCOUNT,
   COUNT(DISTINCT N.TICKETID)/MAX(DATEDIFF(D,N.TICKETDATE,(DATEADD(M,1,N.TICKETDATE))))AS AVGPERDAY      
FROM
   AX2009_1_COPY.DBO.NAT_JOBLINE N
      INNER JOIN AX2009_1_COPY.DBO.SALESLINE S
         ON N.SALESID = S.SALESID
      INNER JOIN AX2009_1_COPY.DBO.CUSTINVOICEJOUR J
         ON N.SALESID = J.SALESID
WHERE
   J.INVOICEID NOT LIKE 'CCR%' AND
   N.TICKETID NOT LIKE 'DMTKT%'
GROUP BY
   YEAR(N.TICKETDATE),
   MONTH(N.TICKETDATE)
ORDER BY
   YEAR(N.TICKETDATE),
   MONTH(N.TICKETDATE)

运行需要12分钟。我不太清楚如何减少查询所需的时间。我知道连接可能会使用一些工作,但我很难找到真正有用的东西。你们能帮助我,给我一些指示或一个好的网站来找到答案吗?

3 个答案:

答案 0 :(得分:3)

首先查看执行计划,以确定查询的哪些部分导致其运行缓慢。如果您要使用SQL Server进行任何工作,那么您应该知道该怎么做。以下是一些值得阅读的体面文章:

一旦检查了执行计划,您就可以确定索引的创建是否可以提高性能。

另一种选择是创建包含持久形式的聚合数据的索引视图。这可以使您免于在运行时进行这些计算...

祝你好运!

答案 1 :(得分:1)

首先,我会确保你有外键索引。 我建议你考虑一下,你是否可以创建人工INT ID,而不是使用varchar ID作为票证和发票。 您可以考虑向数据库添加两列:年和月,因为如果使用年(日期),则无法使用索引。 最后,我将按照此顺序为invoiceid,ticketid,year,month创建组合索引,因为按此顺序它们出现在您的查询中

更新:

其他人建议采用更好的方法,首先你应该调查慢查询的真正问题。虽然您可能想要使用我的一些想法

答案 2 :(得分:0)

一般情况下,请参阅我对相关问题here的回答。如果不这样做,你就不会真正知道什么是错的。

如果我绝对不得不猜测,我怀疑它是对Date函数结果的分组,并有选择地将这些日期非规范化为具有Year和Month列的DateParts表。