我正在重构一些较旧的SQL,它在4年后挣扎,并且有170万行数据。有没有办法改进以下MS 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秒。对该+代表的任何改进
提前致谢。
答案 0 :(得分: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]
答案 1 :(得分:0)
6.25秒接近2m行非常好..也许尝试计算有效行数(你的1/0条件应该允许),而不是值的总和。我认为在oracle环境中效率更高。< / p>