Mengapa kecepatan mengeksekusi pernyataan tergantung pada koneksi jaringan?

31

Sepertinya kecepatan mengeksekusi T-SQL tergantung pada latensi koneksi jaringan terhadap server. Saya berasumsi bahwa jika SQL Server tidak memiliki apa pun untuk dilaporkan kembali ke klien, itu hanya akan mengeksekusi sampai selesai tetapi pengujian menunjukkan cerita lain.

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

Pengujian dijalankan terhadap server yang sama dari komputer yang berbeda menggunakan SSMS. Lokal dijalankan dari Server, di dekatnya ada di jaringan lokal yang sama dan jauh dieksekusi dari kantor lain yang berjarak 500 km terhubung dengan 1 gigabit fiber.

Jelas ada beberapa komunikasi yang terjadi antara SQL Server dan klien yang secara langsung tergantung pada jumlah pernyataan yang dieksekusi.

Saya menggunakan Wireshark untuk melihat apa yang diangkut dan saya tidak bisa mengatakan bahwa saya mengerti banyak tetapi itu adalah tcp.stream yang menukar total 26 MB dalam paket 22740.

Bagaimana dengan fungsi yang tidak berguna?

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)

Itu dijalankan dalam 406 milidetik terlepas dari mana itu dieksekusi. Sepertinya tidak ada komunikasi dengan klien di loop.

Mikael Eriksson
sumber
3
Lihat jawaban ini pada pertanyaan saya juga, silakan stackoverflow.com/a/1547539
gbn

Jawaban:

33

Jelas ada beberapa komunikasi yang terjadi antara SQL Server dan klien yang secara langsung tergantung pada jumlah pernyataan yang dieksekusi.

Ya ada. Secara default, SQL Server mengirim pesan TDSDONE_IN_PROC setelah setiap pernyataan dalam prosedur tersimpan. Pesan mengkomunikasikan informasi status dan jumlah baris untuk pernyataan yang diselesaikan kepada klien.

Anda dapat menekan pengiriman pesan ini menggunakan perintah T-SQL:

SET NOCOUNT ON;

Berikut ini adalah kutipan (penekanan saya) dari entri Books Online untuk perintah ini:

Untuk prosedur tersimpan yang berisi beberapa pernyataan yang tidak mengembalikan banyak data aktual, atau untuk prosedur yang mengandung loop Transact-SQL, pengaturan SET NOCOUNT ke ON dapat memberikan peningkatan kinerja yang signifikan, karena lalu lintas jaringan sangat berkurang.

T & J Terkait: Mengapa loop sederhana menghasilkan ASYNC_NETWORK_IO menunggu?

Paul White mengatakan GoFundMonica
sumber