Perché la velocità di esecuzione delle istruzioni dipende dalla connessione di rete?


31

Sembra che la velocità di esecuzione di T-SQL dipenda dalla latenza della connessione di rete rispetto al server. Ho ipotizzato che se SQL Server non ha nulla di cui riferire al client, verrà eseguito solo fino a quando non viene eseguito, ma i test mostrano un'altra storia.

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

I test vengono eseguiti sullo stesso server da computer diversi utilizzando SSMS. Local viene eseguito dal server, nelle vicinanze si trova sulla stessa rete locale e lontano viene eseguito da un altro ufficio a 500 km di distanza collegato con 1 gigabit in fibra.

Esiste ovviamente una comunicazione tra SQL Server e il client che dipende direttamente dal numero di istruzioni eseguite.

Ho usato Wireshark per vedere cosa viene trasportato e non posso dire di averlo capito molto, ma è stato un flusso di dati tcp che scambiava un totale di 26 MB in 22740 pacchetti.

Che ne dici di una funzione inutile invece?

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)

Viene eseguito in 406 millisecondi indipendentemente da dove viene eseguito. Sembra che non ci sia comunicazione con il client nel loop.


3
Vedi questa risposta anche sulla mia domanda per favore stackoverflow.com/a/1547539
gbn

Risposte:


33

Esiste ovviamente una comunicazione tra SQL Server e il client che dipende direttamente dal numero di istruzioni eseguite.

Si C'è. Per impostazione predefinita, SQL Server invia un messaggio TDSDONE_IN_PROC dopo ogni istruzione in una procedura memorizzata. Il messaggio comunica al client le informazioni sullo stato e sul conteggio delle righe per l'istruzione completata.

Puoi sopprimere l'invio di questi messaggi usando il comando T-SQL:

SET NOCOUNT ON;

Quello che segue è un estratto (la mia enfasi) dalla voce Libri online per questo comando:

Per le procedure memorizzate che contengono diverse istruzioni che non restituiscono molti dati effettivi o per le procedure che contengono loop Transact-SQL, l' impostazione di SET NOCOUNT su ON può fornire un aumento significativo delle prestazioni, poiché il traffico di rete è notevolmente ridotto.

Domande e risposte correlate: Perché un semplice loop risulta in ASYNC_NETWORK_IO in attesa?

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.