Parece que la velocidad de ejecución de T-SQL depende de la latencia de la conexión de red contra el servidor. Supuse que si SQL Server no tiene nada que informar al cliente, simplemente se ejecutará hasta que termine, pero las pruebas muestran otra historia.
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
Las pruebas se ejecutan contra el mismo servidor desde diferentes computadoras que usan SSMS. Lo local se ejecuta desde el servidor, cerca está en la misma red local y lejos se ejecuta desde otra oficina a 500 km de distancia conectada con fibra de 1 gigabit.
Obviamente, hay alguna comunicación entre SQL Server y el cliente que depende directamente del número de declaraciones ejecutadas.
Usé Wireshark para ver lo que se transporta y no puedo decir que entiendo mucho, pero fue un tcp.stream que intercambió un total de 26 MB en 22740 paquetes.
¿Qué tal una función inútil en su lugar?
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)
Se ejecuta en 406 milisegundos, independientemente de dónde se ejecute. Parece que no hay comunicación con el cliente en el bucle.
fuente
Respuestas:
Sí hay. De manera predeterminada, SQL Server envía un mensaje TDS
DONE_IN_PROC
después de cada declaración en un procedimiento almacenado. El mensaje comunica información de estado y recuento de filas para la declaración completa al cliente.Puede suprimir el envío de estos mensajes utilizando el comando T-SQL:
El siguiente es un extracto (mi énfasis) de la entrada de Libros en línea para este comando:
Preguntas y respuestas relacionadas: ¿Por qué un simple bucle resulta en esperas ASYNC_NETWORK_IO?
fuente