Database
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Database

Bất ngờ về hiệu suất và giả định:BẬT SỐ KHOẢN

Nếu bạn đã từng sử dụng Management Studio, thông báo đầu ra này có thể trông quen thuộc:

(1 hàng bị ảnh hưởng)

Điều này đến từ DONE_IN_PROC của SQL Server , được gửi khi hoàn thành thành công bất kỳ câu lệnh SQL nào đã trả về kết quả (bao gồm cả việc truy xuất kế hoạch thực thi, đó là lý do tại sao bạn thấy hai trong số các thông báo này khi bạn thực sự chỉ thực hiện một truy vấn duy nhất).

Bạn có thể chặn các thông báo này bằng lệnh sau:

SET NOCOUNT ON;

Tại sao bạn lại làm vậy? Bởi vì những tin nhắn này là trò chuyện và thường vô ích . Trong các bài thuyết trình về Thói quen xấu và Phương pháp hay nhất của mình, tôi thường nói về việc thêm SET NOCOUNT ON; cho tất cả các thủ tục được lưu trữ và bật nó trong mã ứng dụng để gửi các truy vấn đột xuất. (Tuy nhiên, trong khi gỡ lỗi, bạn có thể muốn một cờ để bật lại thông báo, vì đầu ra có thể hữu ích trong những trường hợp đó.)

Tôi luôn thêm tuyên bố từ chối trách nhiệm rằng lời khuyên để bật tùy chọn này ở mọi nơi không phải là phổ biến; nó phụ thuộc. Các tập bản ghi ADO cũ thực sự hiểu chúng là các tập kết quả, vì vậy việc thêm chúng vào các truy vấn sau khi thực tế có thể thực sự phá vỡ (các) ứng dụng đã bỏ qua chúng theo cách thủ công. Và một số ORM ( ho NHibernate ho ) thực sự phân tích cú pháp kết quả để xác định mức độ thành công của các lệnh DML (ugh!). Vui lòng kiểm tra các thay đổi của bạn.

Tôi biết rằng đã có lúc tôi tự chứng minh rằng những tin nhắn tán gẫu này có thể ảnh hưởng đến hiệu suất, đặc biệt là qua mạng chậm. Nhưng đã lâu rồi, và tuần trước Erin Stellato hỏi tôi đã bao giờ chính thức ghi lại nó chưa. Tôi chưa có, vì vậy hãy bắt đầu. Chúng tôi sẽ thực hiện một vòng lặp rất đơn giản, nơi chúng tôi sẽ cập nhật một biến bảng hàng triệu lần:

SET NOCOUNT OFF;
 
DECLARE @i INT = 1;
DECLARE @x TABLE(a INT);
INSERT @x(a) VALUES(1);
 
SELECT SYSDATETIME();
 
WHILE @i < 1000000
BEGIN
  UPDATE @x SET a = 1;
  SET @i += 1;
END
 
SELECT SYSDATETIME();

Một số điều bạn có thể nhận thấy:

  • Ngăn thông báo tràn ngập các bản sao của (1 row(s) affected) tin nhắn:

  • SELECT SYSDATETIME(); ban đầu không tự hiển thị trong ngăn kết quả cho đến khi toàn bộ lô đã hoàn thành. Điều này là do lũ lụt.
  • Lô này mất khoảng 21 giây để chạy.

Bây giờ, hãy lặp lại điều này mà không có DONE_IN_PROC tin nhắn, bằng cách thay đổi SET NOCOUNT OFF; thành SET NOCOUNT ON; và chạy lại.

Mặc dù ngăn thông báo không còn tràn ngập (các) hàng bị ảnh hưởng, nhưng lô vẫn mất ~ 21 giây để chạy.

Sau đó tôi nghĩ, chờ một chút, tôi biết chuyện gì đang xảy ra. Tôi đang sử dụng một máy cục bộ, không liên quan đến mạng, sử dụng Bộ nhớ dùng chung, tôi chỉ có SSD và bộ nhớ RAM…

Vì vậy, tôi đã lặp lại các bài kiểm tra bằng cách sử dụng bản sao SSMS cục bộ của mình dựa trên Cơ sở dữ liệu Azure SQL từ xa - Tiêu chuẩn, S0, V12. Lần này, các truy vấn mất nhiều thời gian hơn, ngay cả sau khi giảm số lần lặp từ 1.000.000 xuống 100.000. Nhưng một lần nữa không có sự khác biệt rõ ràng về hiệu suất cho dù DONE_IN_PROC tin nhắn đã được gửi hay không. Cả hai lô đều mất khoảng 104 giây và điều này có thể lặp lại qua nhiều lần lặp lại.

Kết luận

Trong nhiều năm, tôi đã hoạt động với ấn tượng rằng SET NOCOUNT ON; là một phần quan trọng của bất kỳ chiến lược hiệu suất nào. Điều này dựa trên những quan sát mà tôi đã thực hiện, được cho là ở một thời đại khác và điều đó ngày nay ít có khả năng hiển thị hơn.

Điều đó nói rằng, tôi sẽ tiếp tục sử dụng SET NOCOUNT ON , ngay cả khi trên phần cứng ngày nay không có sự khác biệt đáng chú ý về hiệu suất. Tôi vẫn cảm thấy khá rõ ràng về việc giảm thiểu lưu lượng mạng nếu có thể. Tôi nên cân nhắc việc triển khai thử nghiệm mà tôi có băng thông hạn chế hơn nhiều (có thể ai đó có đĩa CD AOL mà họ có thể cho tôi mượn?), Hoặc có máy có dung lượng bộ nhớ thấp hơn giới hạn bộ đệm đầu ra của Management Studio, để chắc chắn rằng có không phải là tác động tiềm ẩn trong các tình huống xấu nhất. Trong thời gian chờ đợi, mặc dù nó có thể không thay đổi hiệu suất nhận thấy về ứng dụng của bạn, nhưng nó vẫn có thể giúp ví của bạn luôn bật tùy chọn đặt này, đặc biệt là trong các tình huống như Azure - nơi bạn có thể bị tính phí cho lưu lượng truy cập.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Hướng dẫn dữ liệu:Sử dụng các chức năng của cửa sổ

  2. Tham gia chéo SQL

  3. Cách thiết kế mô hình cơ sở dữ liệu cho hệ thống đặt chỗ rạp chiếu phim

  4. Bí mật của Dominoes, hoặc Mô hình dữ liệu trò chơi Domino

  5. Các nguyên tắc cơ bản về biểu thức bảng, Phần 5 - CTE, các cân nhắc logic