Tại sao tốc độ thực thi các câu lệnh phụ thuộc vào kết nối mạng?


31

Có vẻ như tốc độ thực thi T-SQL phụ thuộc vào độ trễ của kết nối mạng với máy chủ. Tôi giả định rằng nếu SQL Server không có gì để báo cáo lại cho khách hàng, nó sẽ chỉ thực hiện cho đến khi hoàn thành nhưng kiểm tra cho thấy một câu chuyện khác.

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

Các thử nghiệm được thực hiện đối với cùng một máy chủ từ các máy tính khác nhau sử dụng SSMS. Cục bộ được thực thi từ Máy chủ, gần đó nằm trên cùng một mạng cục bộ và ở xa được thực hiện từ một văn phòng khác cách đó 500 km được kết nối với sợi 1 gigabit.

Rõ ràng có một số giao tiếp đang diễn ra giữa SQL Server và máy khách phụ thuộc trực tiếp vào số lượng câu lệnh được thực thi.

Tôi đã sử dụng Wireshark để xem xét những gì được vận chuyển và tôi không thể nói rằng tôi hiểu điều đó nhiều nhưng đó là một tcp.flow trao đổi tổng cộng 26 MB trong 22740 gói.

Làm thế nào về một chức năng vô dụng thay thế?

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)

Nó thực thi trong 406 mili giây bất kể nó được thực thi từ đâu. Có vẻ như không có giao tiếp với khách hàng trong vòng lặp.


3
Xem câu trả lời này cho câu hỏi của tôi quá xin vui lòng stackoverflow.com/a/1547539
gbn

Câu trả lời:


33

Rõ ràng có một số giao tiếp đang diễn ra giữa SQL Server và máy khách phụ thuộc trực tiếp vào số lượng câu lệnh được thực thi.

Có, có. Theo mặc định, SQL Server gửi tin nhắn TDSDONE_IN_PROC sau mỗi câu lệnh trong một thủ tục được lưu trữ. Thông báo truyền thông tin về trạng thái và số hàng cho câu lệnh đã hoàn thành cho khách hàng.

Bạn có thể ngăn chặn việc gửi các tin nhắn này bằng lệnh T-SQL:

SET NOCOUNT ON;

Sau đây là trích xuất (nhấn mạnh của tôi) từ mục Sách trực tuyến cho lệnh này:

Đối với các thủ tục được lưu trữ có chứa một số câu lệnh không trả về nhiều dữ liệu thực tế hoặc cho các thủ tục có chứa các vòng lặp Transact-SQL, việc đặt SET NOCOUNT thành ON có thể tăng hiệu suất đáng kể, vì lưu lượng mạng giảm đáng kể.

Câu hỏi liên quan: Tại sao một vòng lặp đơn giản dẫn đến ASYNC_NETWORK_IO chờ đợi?

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.