看起来执行 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())
Run Code Online (Sandbox Code Playgroud)
exec UselessLoop 100000
Server Milliseconds
local 53
nearby 63
faraway 660
Run Code Online (Sandbox Code Playgroud)
exec UselessLoop 1000000
Server Milliseconds
local 546
nearby 640
faraway 6183
Run Code Online (Sandbox Code Playgroud)
使用 SSMS 对来自不同计算机的同一服务器执行测试。本地从服务器执行,附近在同一个本地网络上,远处是从 500 公里外的另一个办公室执行,通过 1 Gb 光纤连接。
显然,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
Run Code Online (Sandbox Code Playgroud)
print dbo.UDFUselessLoop(1000000)
无论从何处执行,它都会在 406 毫秒内执行。看起来循环中没有与客户端的通信。
Pau*_*ite 33
显然,SQL Server 和客户端之间存在一些直接依赖于执行的语句数量的通信。
就在这里。默认情况下,SQL Server在存储过程中的每个语句之后发送TDSDONE_IN_PROC消息。该消息将已完成语句的状态和行计数信息传达给客户端。
您可以使用 T-SQL 命令禁止发送这些消息:
SET NOCOUNT ON;
Run Code Online (Sandbox Code Playgroud)
以下是此命令的联机丛书条目的摘录(我的重点):
对于包含多个不返回太多实际数据的语句的存储过程,或者对于包含 Transact-SQL 循环的过程,将 SET NOCOUNT 设置为 ON 可以显着提高性能,因为网络流量大大减少。
相关问答:为什么简单的循环会导致 ASYNC_NETWORK_IO 等待?
| 归档时间: |
|
| 查看次数: |
1042 次 |
| 最近记录: |