2010-02-11 56 views
1

我正在重构一些较旧的SQL,这是在4年和1.7m行数据之后挣扎。有没有改善以下MS SQL查询的方式:寻找SQL计数性能改进。

SELECT  ServiceGetDayRange_1.[Display Start Date], 
SUM (CASE WHEN Calls.line_date BETWEEN [Start Date] AND [End Date] THEN 1 ELSE 0 END) AS PerDayCount 
FROM   dbo.ServiceGetDayRange(GETUTCDATE(), 30, @standardBias, @daylightBias, @DST_startMonth, @DST_endMonth, @DST_startWeek, @DST_endWeek, @DST_startHour, @DST_endHour, @DST_startDayNumber, @DST_endDayNumber) AS ServiceGetDayRange_1 CROSS JOIN 
         (select [line_date] from dbo.l_log where dbo.l_log.line_date > dateadd(day,-31,GETUTCDATE())) as Calls 
GROUP BY ServiceGetDayRange_1.[Display Start Date], ServiceGetDayRange_1.[Display End Date] 
ORDER BY [Display Start Date] 

它在过去30天计数日志条目(ServiceGetDayRange函数返回表,详细范围,TZ对齐)密谋图表..无用的信息,但我不是客户。

执行计划规定执行时间的99%用于计算条目..正如您所期望的那样。在计算TZ偏移时很少有开销(记住最多30行)。

愚蠢我以为'啊,索引视图',但后来意识到我不能绑定到一个函数。

当前执行时间,如果6.25秒。任何改善+ rep

在此先感谢。

回答

3

如果您将CASE转变为WHERE,速度会更快吗?

SELECT  ServiceGetDayRange_1.[Display Start Date], COUNT(*) AS PerDayCount 
FROM  dbo.ServiceGetDayRange(GETUTCDATE(), 30, @standardBias, @daylightBias, @DST_startMonth, @DST_endMonth, @DST_startWeek, @DST_endWeek, @DST_startHour, @DST_endHour, @DST_startDayNumber, @DST_endDayNumber) AS ServiceGetDayRange_1 CROSS JOIN 
         (select [line_date] from dbo.l_log where dbo.l_log.line_date > dateadd(day,-31,GETUTCDATE())) as Calls 
WHERE Calls.line_date BETWEEN [Start Date] AND [End Date] 
GROUP BY ServiceGetDayRange_1.[Display Start Date], ServiceGetDayRange_1.[Display End Date] 
ORDER BY [Display Start Date] 
+0

omg ...其整个4.5秒更快...我实际上打折了,因为我认为它owuld计数日期范围(即总是30),您先生,是一个绅士。 – 2010-02-11 00:58:13

+1

很高兴听到它。猜测,我认为对于CASE来说,它必须访问每一行并以不可优化的方式评估表达式。 COUNT(*)/ WHERE有机会更好地使用索引,也许... – 2010-02-11 01:06:51

0

6.25秒为近200行是相当不错的..也许尝试有效行数(您的条件1/0应该允许),而不是值的总和。我认为这是更有效oracle环境。

+0

我其实也认为6.25秒并不坏,所有的事情都是一致的,差不多就是这样 - 很高兴我没有; t。我现在知道基于案例测试的计数并不总是更好。 – 2010-02-11 01:01:24