create procedure UselessLoop
@I int
as
declare @D datetime = getdate()
while @I > 0 set @I -= 1
print datediff(millisecond, @D, getdate())
exec UselessLoop 100000
< Server Milliseconds
local 53
nearby 63
faraway 660
exec UselessLoop 1000000
Server Milliseconds
local 546
nearby 640
faraway 6183
测试是使用SSMS在不同计算机上针对同一服务器执行的。本地是从服务器执行的,附近是在同一个本地网络上,而遥远的是从500公里外的另一个办公室执行的,该办公室连接了1吉比特光纤。
显然,SQL Server与SQL Server之间存在一些通信。客户端直接取决于执行的语句数。
我使用Wireshark来查看传输的内容,我不能说我理解得太多,但这是一个tcp.stream交换了总计22740数据包中26 MB的数据。
无用的函数又如何呢?
create function dbo.UDFUselessLoop(@I int)
returns int
as
begin
declare @D datetime = getdate()
while @I > 0 set @I -= 1
return datediff(millisecond, @D, getdate())
end
print dbo.UDFUselessLoop(1000000)
它在406毫秒内执行,无论它在哪里从执行。看起来循环中没有与客户端的通信。
#1 楼
很明显,SQL Server和客户端之间正在进行某些通信,而这些通信直接取决于所执行的语句数。
是的。默认情况下,SQL Server在存储过程中的每个语句之后发送TDS
DONE_IN_PROC
消息。该消息将已完成语句的状态和行计数信息传达给客户端。您可以使用T-SQL命令禁止发送这些消息:
SET NOCOUNT ON;
下面是此命令的联机丛书摘录(重点):
对于包含多个不会返回大量实际数据的语句的存储过程,或者对于包含Transact-SQL循环的过程,将SET NOCOUNT设置为ON可以显着提高性能,因为大大减少了网络流量。
相关问答:为什么ASYNC_NETWORK_IO等待中的简单循环结果?
评论
也在我的问题上看到这个答案,请stackoverflow.com/a/1547539