为什么执行语句的速度取决于网络连接?


31

看起来执行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毫秒内执行。看起来循环中没有与客户端的通信。


3
也在我的问题上看到这个答案,请stackoverflow.com/a/1547539
gbn 2014年

Answers:


33

显然,SQL Server与客户端之间正在进行某种通信,直接取决于所执行语句的数量。

就在这里。默认情况下,SQL Server 在存储过程中的每个语句之后发送TDS DONE_IN_PROC消息。该消息将已完成语句的状态和行计数信息传达给客户端。

您可以使用T-SQL命令禁止发送这些消息:

SET NOCOUNT ON;

以下是此命令从联机丛书条目中的摘录(我的重点):

对于包含多个不返回大量实际数据的语句的存储过程,或者对于包含Transact-SQL循环的过程,将SET NOCOUNT设置为ON可以显着提高性能,因为可以大大减少网络流量。

相关问答:为什么简单循环会导致ASYNC_NETWORK_IO等待?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.