¿Por qué la velocidad de ejecución de las declaraciones depende de la conexión de red?


31

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.


3
Vea esta respuesta en mi pregunta también, por favor stackoverflow.com/a/1547539
gbn

Respuestas:


33

Obviamente, hay alguna comunicación entre SQL Server y el cliente que depende directamente del número de declaraciones ejecutadas.

Sí hay. De manera predeterminada, SQL Server envía un mensaje TDSDONE_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:

SET NOCOUNT ON;

El siguiente es un extracto (mi énfasis) de la entrada de Libros en línea para este comando:

Para los procedimientos almacenados que contienen varias declaraciones que no devuelven muchos datos reales, o para los procedimientos que contienen bucles Transact-SQL, establecer SET NOCOUNT en ON puede proporcionar un aumento significativo del rendimiento, ya que el tráfico de red se reduce considerablemente.

Preguntas y respuestas relacionadas: ¿Por qué un simple bucle resulta en esperas ASYNC_NETWORK_IO?

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.