Pourquoi la vitesse d'exécution des instructions dépend-elle de la connexion réseau?

31

Il semble que la vitesse d'exécution de T-SQL dépende de la latence de la connexion réseau par rapport au serveur. J'ai supposé que si SQL Server n'a rien à signaler au client, il s'exécutera jusqu'à ce qu'il soit terminé, mais les tests montrent une autre histoire.

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

Les tests sont exécutés sur le même serveur à partir d'ordinateurs différents utilisant SSMS. Local est exécuté à partir du serveur, à proximité se trouve sur le même réseau local et lointain est exécuté à partir d'un autre bureau à 500 km connecté avec 1 fibre gigabit.

Il y a évidemment une communication en cours entre SQL Server et le client qui dépend directement du nombre d'instructions exécutées.

J'ai utilisé Wireshark pour regarder ce qui est transporté et je ne peux pas dire que je comprends beaucoup mais c'était un tcp.stream échangeant un total de 26 Mo en 22740 paquets.

Que diriez-vous d'une fonction inutile à la place?

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)

Il s'exécute en 406 millisecondes, peu importe d'où il est exécuté. Il semble qu'il n'y ait aucune communication avec le client dans la boucle.

Mikael Eriksson
la source
3
Voir cette réponse sur ma question aussi s'il vous plaît stackoverflow.com/a/1547539
gbn

Réponses:

33

Il y a évidemment une communication en cours entre SQL Server et le client qui dépend directement du nombre d'instructions exécutées.

Oui il y a. Par défaut, SQL Server envoie un message TDSDONE_IN_PROC après chaque instruction d'une procédure stockée. Le message communique au client les informations d'état et de nombre de lignes de l'instruction terminée.

Vous pouvez supprimer l'envoi de ces messages à l'aide de la commande T-SQL:

SET NOCOUNT ON;

Ce qui suit est un extrait (je souligne) de l'entrée de documentation en ligne pour cette commande:

Pour les procédures stockées qui contiennent plusieurs instructions qui ne renvoient pas beaucoup de données réelles, ou pour les procédures qui contiennent des boucles Transact-SQL, la définition de SET NOCOUNT sur ON peut améliorer considérablement les performances, car le trafic réseau est considérablement réduit.

Questions et réponses connexes: Pourquoi une simple boucle entraîne-t-elle des attentes ASYNC_NETWORK_IO?

Paul White dit GoFundMonica
la source