Похоже, что скорость выполнения 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, который обменивался в общей сложности 26 МБ в 22740 пакетах.
Как насчет бесполезной функции вместо этого?
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:
Ниже приведен отрывок (мой акцент) из записи Books Online для этой команды:
Связанные вопросы и ответы: почему простой цикл приводит к ожиданию ASYNC_NETWORK_IO?
источник