Чому швидкість виконання операторів залежить від мережевого з'єднання?


31

Схоже, швидкість виконання T-SQL залежить від затримки мережевого підключення до сервера. Я припускав, що якщо SQL Server не має про що звітувати клієнтові, він буде просто виконуватись, поки це не буде зроблено, але тестування покаже іншу історію.

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

Тести виконуються на одному і тому ж сервері з різних комп'ютерів за допомогою SSMS. Локальний виконується з Сервера, поруч знаходиться в тій же локальній мережі, а далекий виконується з іншого офісу, розташованого за 500 км, з'єднаного з 1 гігабітним волокном.

Очевидно, що між SQL Server і клієнтом відбувається комунікація, яка безпосередньо залежить від кількості виконаних операторів.

Я використовував Wireshark, щоб подивитися на те, що транспортується, і я не можу сказати, що я так добре розумію, але це був tcp.stream, обмінюючи в цілому 26 МБ в 22740 пакетах.

А як щодо марної функції замість цього?

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)

Він виконується за 406 мілісекунд незалежно від того, звідки він виконаний. Схоже, немає зв'язку з клієнтом у циклі.


3
Дивіться цей відповідь на моє запитання теж будь ласка , stackoverflow.com/a/1547539
ГБН

Відповіді:


33

Очевидно, що між SQL Server і клієнтом відбувається комунікація, яка безпосередньо залежить від кількості виконаних операторів.

Так, є. За замовчуванням SQL Server надсилає повідомлення TDSDONE_IN_PROC після кожного заяви у збереженій процедурі. Повідомлення передає клієнтові інформацію про стан та кількість рядків для завершеного оператора.

Ви можете придушити надсилання цих повідомлень за допомогою команди T-SQL:

SET NOCOUNT ON;

Далі - уривок (мій акцент) із запису Книги Інтернет для цієї команди:

Для збережених процедур, що містять кілька операторів, які не повертають багато фактичних даних, або для процедур, що містять петлі Transact-SQL, встановлення SET NOCOUNT на ON може забезпечити значне підвищення продуктивності, оскільки мережевий трафік значно скорочується.

Пов'язані запитання та запитання: Чому простий цикл призводить до появи ASYNC_NETWORK_IO?

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.