平台: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
答案 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