Parece que a velocidade de execução do T-SQL depende da latência da conexão de rede com o servidor. Presumi que, se o SQL Server não tiver nada para relatar ao cliente, ele será executado até que seja concluído, mas o teste mostra outra história.
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
Os testes são executados no mesmo servidor de diferentes computadores usando o SSMS. O local é executado a partir do servidor, o local é executado na mesma rede local e o distante é executado a partir de outro escritório a 500 km de distância conectado com fibra de 1 gigabit.
Obviamente, há alguma comunicação acontecendo entre o SQL Server e o cliente que depende diretamente do número de instruções executadas.
Usei o Wireshark para ver o que é transportado e não posso dizer que entendo muito, mas era um tcp.stream trocando um total de 26 MB em 22740 pacotes.
Que tal uma função inútil?
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)
Ele é executado em 406 milissegundos, independentemente de onde é executado. Parece que não há comunicação com o cliente no loop.
Sim existe. Por padrão, o SQL Server envia uma mensagem TDS
DONE_IN_PROC
após cada instrução em um procedimento armazenado. A mensagem comunica informações de status e contagem de linhas para a instrução concluída ao cliente.Você pode suprimir o envio dessas mensagens usando o comando T-SQL:
O seguinte é um extrato (minha ênfase) da entrada do Books Online para este comando:
Perguntas e respostas relacionadas: por que um loop simples resulta em esperas ASYNC_NETWORK_IO?