如何在不影响测试结果的情况下测试大型查询(例如600k行)的性能?虽然两个查询都将输出到同一位置,但所有事情都是平等的。但我想加快我的测试周期,并且我认为SQL Server Management Studio的输出设置正在妨碍我的工作。目前我正在使用文本输出,但我希望有更好的选择。
我认为这会影响我的数字,因为数据库在我的本地机器上。
编辑:关于在这里执行WHERE 1 = 0的问题(认为连接会发生但没有输出),但我测试了一下,它并不起作用 - 不是查询性能的有效指标。
在查询之前,您可以执行SET ROWCOUNT 1
操作。我不确定这是否正是您想要的,但它将避免等待大量数据返回,从而为您提供准确的计算成本。
但是,如果您在查询中添加客户端统计信息,其中一个数字是服务器回复等待时间,该时间将给出不包括将数据传输到网络所需时间的服务器计算时间。
你可以使用SET STATISTICS TIME ON来测量服务器的时间。而且你可以在SSMS上使用查询/包括客户端统计信息 (Shift+Alt+S) 来获取有关客户端时间使用情况的详细信息。请注意,SQL查询不会在运行完后将结果返回给客户端,而是在返回结果时自动运行,并且甚至会在通信通道已满时暂停执行。
唯一忽略向客户端发送结果数据包的查询场景是激活。但是当你测量性能时还应考虑返回输出到客户端的时间。你确定自己的客户端比SSMS更快吗?
SET ROWCOUNT 1
会在返回第一行后停止处理,这意味着除非计划恰好有一个阻塞操作符,否则结果将是无用的。
以一个微不足道的例子为例:
SELECT * FROM TableX
实际上,此查询的成本将严重取决于TableX
中的行数。
使用SET ROWCOUNT 1
不会显示任何内容。无论TableX
有1行还是10亿行,它都将在返回第一行后停止执行。
我经常将SELECT
结果分配给变量,以便能够查看诸如逻辑读取之类的内容,而不会被SSMS显示结果所减慢速度。
SET STATISTICS IO ON
DECLARE @name nvarchar(35),
@type nchar(3)
SELECT @name = name,
@type = type
FROM master..spt_values
有一个相关的Connect Item请求在SSMS和/或TSQL中提供“在服务器上丢弃结果”选项
有很多更正确的答案,但我认为真正的问题是当我偶然发现这个问题时自己问的: 我有一个查询A和一个查询B在相同的测试数据上。哪个更快?我想要快速而简单地检查。对我来说,答案是 - 临时表(在此创建临时表的开销很容易被忽略)。这只能在性能/测试/开发服务器上完成!
查询A:
DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS (to clear statistics
SELECT * INTO #temp1 FROM ...
查询 B
DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS
SELECT * INTO #temp2 FROM ...
你可以做的最好的事情就是检查查询执行计划(按下Ctrl+L)。这将为您提供最佳性能的最佳猜测。
我认为WHERE 1=0
的where子句肯定是在SQL Server端而不是Management Studio上发生的。没有结果会被返回。
你的数据库引擎是否在你运行Mgmt Studio的同一台机器上?
你可以:
这只是将在Mgmt Studio中绘制网格所花费的周期移动了。也许将结果输出到文本会更有效率。隐藏窗格将节省Mgmt Studio上绘制数据所需的周期。它仍然被返回到Mgmt Studio,因此它并没有节省很多周期。
如果不输出结果,您如何测试查询的性能?如果测试无法告诉您查询的执行情况,那么加快测试速度是毫无意义的。难道您真的想在将其推送到生产后才发现这个糟糕的查询需要花费十分钟才能返回数据吗?
当然,返回 600,000 条记录需要一些时间。它在您的用户界面中也是如此,在查询窗口中可能比在网络上传输信息要慢。
SET ROWCOUNT 1
的成本可能与不使用此值完全不同。执行在返回第一行后停止,因此它会低估真实成本,并且计划可能在有和没有ROWCOUNT
的情况下不同。 - Martin Smith