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

Bee*_*ems 1 t-sql sql-server

平台: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
Run Code Online (Sandbox Code Playgroud)

最后的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

Bee*_*ems 6

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

当日期范围较小时,SQL查询需要更长的时间?

使用那篇文章中没有链接的MSDN文章,但是这篇文章在这里:

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

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

我运行了以下内容:

USE db_reports;
GO
UPDATE STATISTICS tb_applicationusage;
GO
Run Code Online (Sandbox Code Playgroud)

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

谢谢,Beems