Warum hängt die Geschwindigkeit der Ausführung von Anweisungen von der Netzwerkverbindung ab?

31

Offenbar hängt die Ausführungsgeschwindigkeit von T-SQL von der Latenz der Netzwerkverbindung zum Server ab. Ich ging davon aus, dass SQL Server, wenn er dem Client nichts zu melden hat, nur so lange ausgeführt wird, bis er fertig ist, aber das Testen zeigt eine andere Geschichte.

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

Die Tests werden mithilfe von SSMS auf demselben Server von verschiedenen Computern aus ausgeführt. Lokal wird vom Server ausgeführt, in der Nähe im selben lokalen Netzwerk und weit entfernt von einem anderen Büro in 500 km Entfernung, das mit einer 1-Gigabit-Glasfaser verbunden ist.

Zwischen SQL Server und dem Client findet offensichtlich eine Kommunikation statt, die direkt von der Anzahl der ausgeführten Anweisungen abhängt.

Ich habe Wireshark verwendet, um zu sehen, was transportiert wird, und ich kann nicht sagen, dass ich so viel verstehe, aber es war ein tcp.stream, der insgesamt 26 MB in 22740 Paketen austauschte.

Wie wäre es stattdessen mit einer nutzlosen Funktion?

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)

Es wird in 406 Millisekunden ausgeführt, unabhängig davon, von wo es ausgeführt wird. Es scheint keine Kommunikation mit dem Client in der Schleife zu geben.

Mikael Eriksson
quelle
3
Siehe auch diese Antwort auf meine Frage stackoverflow.com/a/1547539
gbn

Antworten:

33

Zwischen SQL Server und dem Client findet offensichtlich eine Kommunikation statt, die direkt von der Anzahl der ausgeführten Anweisungen abhängt.

Ja da ist. Standardmäßig sendet SQL Server nach jeder Anweisung in einer gespeicherten Prozedur eine TDS- DONE_IN_PROCNachricht . In der Nachricht werden Status- und Zeilenanzahlinformationen für die abgeschlossene Anweisung an den Client übermittelt.

Sie können das Senden dieser Nachrichten mit dem T-SQL-Befehl unterdrücken:

SET NOCOUNT ON;

Das Folgende ist ein Auszug (mein Schwerpunkt) aus der Onlinedokumentation für diesen Befehl:

Wenn Sie für gespeicherte Prozeduren, die mehrere Anweisungen enthalten, die nicht viele tatsächliche Daten zurückgeben, oder für Prozeduren, die Transact-SQL-Schleifen enthalten, SET NOCOUNT auf ON setzen, kann dies zu einer deutlichen Leistungssteigerung führen, da der Netzwerkverkehr erheblich reduziert wird.

Verwandte Fragen und Antworten : Warum führt eine einfache Schleife dazu, dass ASYNC_NETWORK_IO wartet?

Paul White sagt GoFundMonica
quelle