Wygląda na to, że szybkość wykonywania T-SQL zależy od opóźnienia połączenia sieciowego z serwerem. Założyłem, że jeśli SQL Server nie ma nic do zgłaszania klientowi, będzie po prostu działał, dopóki nie zostanie wykonane, ale testy pokazują inną historię.
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
Testy są wykonywane na tym samym serwerze z różnych komputerów za pomocą SSMS. Lokalny jest wykonywany z serwera, w pobliżu jest w tej samej sieci lokalnej, a daleki jest wykonywany z innego biura 500 km połączonego 1 gigabitowym włóknem.
Oczywiście między programem SQL Server a klientem zachodzi pewna komunikacja, która zależy bezpośrednio od liczby wykonanych instrukcji.
Użyłem Wiresharka, aby zobaczyć, co jest transportowane i nie mogę powiedzieć, że tak dużo rozumiem, ale był to tcp.stream wymieniający w sumie 26 MB w 22740 pakietach.
Co powiesz na bezużyteczną funkcję?
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)
Wykonuje się w 406 milisekundach bez względu na to, skąd jest wykonywany. Wygląda na to, że w pętli nie ma komunikacji z klientem.
źródło
Odpowiedzi:
Tak jest. Domyślnie program SQL Server wysyła komunikat TDS
DONE_IN_PROC
po każdej instrukcji w procedurze przechowywanej. Komunikat przekazuje klientowi informacje o statusie i liczbie wierszy dla zakończonej instrukcji.Możesz zablokować wysyłanie tych wiadomości za pomocą polecenia T-SQL:
Poniżej znajduje się fragment (mój nacisk) z pozycji Books Online dla tego polecenia:
Powiązane pytania i odpowiedzi: Dlaczego prosta pętla powoduje, że ASYNC_NETWORK_IO czeka?
źródło