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.
la source
Réponses:
Oui il y a. Par défaut, SQL Server envoie un message TDS
DONE_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:
Ce qui suit est un extrait (je souligne) de l'entrée de documentation en ligne pour cette commande:
Questions et réponses connexes: Pourquoi une simple boucle entraîne-t-elle des attentes ASYNC_NETWORK_IO?
la source