为什么短日期范围的SQL查询运行缓慢,而长距离运行很快?

时间:2015-02-12 17:33:02

标签: sql-server tsql

平台:SQL Server 2008 R2

我有一个相当复杂的SQL查询,它查询(2)不同的数据库并根据记录的日期范围收集报告。搜索超过3,000,000行的日期范围(例如2个月)几乎是即时的。但是,搜索7天的短日期范围需要将近两分钟。对于我的生活,我无法理解为什么会这样。这是以下查询:

;with cte_assets as ( 
 select a.f_locationid, a.f_locationparent, 0 as [lev], convert(varchar(30), '0_' + convert(varchar(10), f_locationid)) lineage 
 from [db_assets].[dbo].[tb_locations] a where f_locationID = '366' UNION ALL 
 select a.f_locationid 
           ,a.f_locationparent 
           ,c.[lev] + 1 
           ,convert(varchar(30), lineage + '_' + convert(varchar(10), a.f_locationid)) 
    from   cte_assets c 
    join   [db_assets].[dbo].[tb_locations] a 
           on a.f_locationparent = c.f_locationID 
 ),
 cte_a AS 
 ( 
    select f_assetnetbiosname as 'Computer Name' 
    from cte_assets c 
    JOIN [db_assets].[dbo].[tb_assets] ass on ass.f_assetlocation = c.f_locationID 
 ) 
      select apps.f_applicationname, apps.f_applicationID, sum(f_runtime/60) [RunTime] 
 from cte_a c 
 JOIN [db_reports].[dbo].[tb_applicationusage] ss on ss.f_computername = c.[Computer Name] 
 JOIN [db_reports].[dbo].[tb_applications] apps 
 ON ss.f_application = apps.f_applicationID 
 WHERE ss.f_runtime IS NOT NULL AND f_starttime BETWEEN '1/26/2015 10:55:03 AM' AND '2/12/2015 10:55:03 AM'
 group by apps.f_applicationname, ss.f_application, apps.f_applicationID 
 ORDER BY RunTime DESC

最后的WHERE子句(倒数第3行)是指定日期范围的位置。 BETWEEN '1/26/2015 10:55:03 AM' AND '2/12/2015 10:55:03 AM'查询中显示的日期范围可以很快发挥作用。如果我们将查询更改为例如BETWEEN '1/27/2015 10:55:03 AM' AND '2/12/2015 10:55:03 AM'(仅一天之后),则需要两分钟才能运行。我完全不知道为什么短程会导致查询运行得更慢。任何帮助表示赞赏。

谢谢, Beems

1 个答案:

答案 0 :(得分:6)

我道歉,我应该先用Google搜索这个问题。我在另一篇关于需要更新统计信息的StackOverflow帖子上找到了答案:

SQL query takes longer time when date range is smaller?

使用该文章中未链接的MSDN文章,但this one here

  

更新表或索引视图上的查询优化统计信息。通过   默认情况下,查询优化器已根据需要更新统计信息   改进查询计划;在某些情况下,您可以改善查询   使用UPDATE STATISTICS或存储过程的性能   sp_updatestats比默认更频繁地更新统计信息   更新。

     

更新统计信息可确保查询使用最新版本进行编译   统计。但是,更新统计信息会导致查询重新编译。   我们建议不要过于频繁地更新统计信息,因为有一个   在改进查询计划和时间之间的性能权衡   需要重新编译查询。具体的权衡取决于你的   应用。 UPDATE STATISTICS可以使用tempdb对样本进行排序   用于构建统计信息的行。

我运行了以下内容:

USE db_reports;
GO
UPDATE STATISTICS tb_applicationusage;
GO

2秒后更新完成,我的短期近期查询现在运行得很快。

谢谢, Beems