关于时间统计,执行计划和“打印”的问题

时间:2010-01-22 23:42:03

标签: sql-server sql-server-2005

在尝试确定我的大型查询的哪个区域导致性能问题时,我采取了三个步骤。包括执行计划,在我认为可能导致问题的部分之前和之后立即设置时间统计和打印。例如:

print '1'
SELECT ID FROM Test
print '2'

当我查看我的执行计划时,它说某个部分占据了“成本”的很大一部分。当我将这个百分比与我print '1'print '2'之间的经过时间进行比较时,似乎没有办法让百分比接近。

依靠打印值和时间统计数据来估算成本是否安全?如果是的话,我是否有必要关注印刷值之间经过一段时间而不是估计成本的区域?

2 个答案:

答案 0 :(得分:1)

这不是一个安全的赌注,因为PRINT语句被缓冲输出 - 它们不是立竿见影的。执行计划是寻找性能问题的好地方,因为它可以确定最昂贵的部件的位置,并帮助识别丢失索引等内容(例如,如果您看到表扫描)。

您还应该使用SQL Profiler - 监控SQL:StmtStartingSQL:StmtCompleted事件 - 这将显示每个语句执行所需时间的统计信息(StmtCompleted是您的主要信息)感兴趣)。

答案 1 :(得分:1)

如果您只打印“1”并打印“2”,则测量在SSMS消息窗格中看到消息之间的时间,然后您将成为服务器和客户端之间输出缓冲的牺牲品。 print '1' 可能不会立即发送回客户端,而SqlClient,ADO.Net和SSMS也会对自己进行缓冲。总的来说,您可能会在SSMS结果“消息”面板中看到“1”,比实际发生的时间晚。更好的是从getdate()打印时间,而不仅仅是'1'。这样你可以从等式中取出缓冲,你可以在消息本身看到服务器执行'print'的时间,而不是SSMS显示输出的时间。

SET STATISTICS TIME ON总是更准确,但有时很难理解它所指的是哪种陈述。

我通常做的是这样的事情:

declare @nowString varchar(100);
declare @start datetime, @end datetime, @rc int, @elapsed int;

set @start = getdate();

select many, fields 
from bigtable 
join manytables on condition = complex 
where matches = many
order by wacky sort;

set @rc = @@rowcount;
set @end = getdate();
set @elapsed = datediff(ms, @start, @end);
set @nowString = cast(varchar(100), getdate(), 14);
raiserror(N'%s: At select No 1. Selected %i rows in %i ms', 10, 1, %nowString, @rc, @elapsed);

set @start = getdate();
...next select here...