看起来执行 T-SQL 的速度取决于与服务器的网络连接延迟。我假设如果 SQL Server 没有什么可向客户端报告的,它会一直执行直到完成,但测试显示了另一个故事。
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 和客户端之间正在进行一些通信,这直接取决于执行的语句数。
我使用 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 毫秒内执行。看起来循环中没有与客户端通信。
就在这里。默认情况下,SQL Server在存储过程中的每个语句之后发送一条TDS
DONE_IN_PROC
消息。该消息将已完成语句的状态和行计数信息传达给客户端。您可以使用 T-SQL 命令禁止发送这些消息:
以下是此命令的联机丛书条目的摘录(我强调的) :
相关问答:为什么一个简单的循环会导致 ASYNC_NETWORK_IO 等待?