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

Theo dõi cập nhật thống kê đồng bộ

Giới thiệu

Trình tối ưu hóa truy vấn SQL Server sử dụng thống kê trong quá trình biên dịch truy vấn để giúp xác định kế hoạch truy vấn tối ưu. Theo mặc định, nếu trình tối ưu hóa nhận thấy thống kê đã lỗi thời do có quá nhiều thay đổi đối với một bảng, thì nó sẽ cập nhật thống kê ngay lập tức trước khi quá trình biên dịch truy vấn có thể tiếp tục (chỉ thống kê mà nó cần, không phải tất cả thống kê cho bảng) .

Lưu ý rằng “quá nhiều” là không cụ thể vì nó thay đổi theo phiên bản và liệu cờ theo dõi 2371 có được bật hay không - hãy xem phần AUTO_UPDATE_STATISTICS của trang này để biết chi tiết.

Sự cố với cập nhật thống kê đồng bộ

Cập nhật đồng bộ số liệu thống kê trước khi biên dịch rõ ràng gây ra sự chậm trễ và làm cho truy vấn mất nhiều thời gian hơn để biên dịch và thực thi. Mức độ chậm trễ phụ thuộc vào một số yếu tố, bao gồm:

  • Có bao nhiêu bảng tham gia vào truy vấn đã đạt đến ngưỡng "quá nhiều thay đổi"
  • Có bao nhiêu thống kê cho mỗi bảng trong số đó phải được cập nhật vì chúng cần thiết để tổng hợp
  • Có bao nhiêu hàng trong các bảng có liên quan
  • Các tùy chọn được chỉ định khi mỗi thống kê được tạo (ví dụ:FULLSCAN và PERSIST_SAMPLE_PERCENT =ON)

Vì vậy, có thể có độ trễ dường như ngẫu nhiên, điều này có thể gây ra sự cố trong một số trường hợp, đặc biệt nếu ứng dụng có bộ thời gian chờ truy vấn rất thấp.

Tránh cập nhật thống kê đồng bộ

Có nhiều cách khác nhau để tránh cập nhật thống kê đồng bộ, chẳng hạn như:

  • Đặt AUTO_UPDATE_STATISTICS thành TẮT, thao tác này sẽ tắt tất cả các cập nhật tự động và có nghĩa là bạn sẽ cần thực hiện bảo trì thống kê của riêng mình để tránh khả năng xuất hiện các kế hoạch truy vấn dưới mức tối ưu từ các thống kê lỗi thời.
  • Đặt AUTO_UPDATE_STATISTICS_ASYNC thành BẬT, do đó, khi trình tối ưu hóa nhận thấy một thống kê cần được cập nhật, nó sẽ tiếp tục với quá trình biên dịch và tác vụ nền sẽ cập nhật thống kê sau đó một chút. Điều này chỉ hoạt động nếu bạn cũng đặt AUTO_UPDATE_STATISTICS thành BẬT.
  • Thực hiện bảo trì thống kê thường xuyên, do đó, việc cập nhật thống kê đồng bộ hoặc không đồng bộ tự động hoàn toàn không xảy ra.

Có rất nhiều cuộc tranh luận trong cộng đồng SQL Server xung quanh việc có nên bật cập nhật thống kê không đồng bộ hay không. Tôi đã hỏi người vợ đáng yêu của mình, Kimberly L. Tripp, ý kiến ​​của cô ấy là gì và cô ấy luôn khuyên bạn nên bật nó và cô ấy quên nhiều về số liệu thống kê hơn những gì tôi chưa từng biết, vì vậy tôi tin cô ấy. ☺

Theo dõi cập nhật thống kê đồng bộ

Chưa bao giờ có cách rõ ràng để biết liệu một truy vấn có mất nhiều thời gian hay không vì nó đang chờ cập nhật thống kê đồng bộ. Bạn có thể biết * sau khi * cập nhật thống kê đã hoàn tất nếu bạn có một phiên Sự kiện mở rộng đang chạy xem cho auto_stats sự kiện và lọc trên async cột đang được đặt thành 0. Tuy nhiên, cột đó trong đầu ra sự kiện chỉ được thêm vào SQL Server 2017 và bạn cũng phải định cấu hình một hành động nắm bắt một thứ gì đó để xác định truy vấn có liên quan.

Bây giờ trong SQL Server 2019, có kiểu chờ WAIT_ON_SYNCHRONOUS_STATISTICS_UPDATE và thoạt nhìn, có vẻ như nó sẽ dễ dàng cho phép bạn xem liệu một truy vấn có đang chờ cập nhật thống kê đồng bộ hay không bằng cách chỉ cần xem trong sys.dm_os_waiting_tasks để xem truy vấn hiện đang là gì đang chờ đợi.

Thật không may, đó không phải là trường hợp.

Thuật ngữ “chờ đợi” hơi gây hiểu nhầm ở đây vì trong trường hợp này, chuỗi không thực sự đang đợi. Loại chờ mới này là một ví dụ về cái được gọi là chờ “phủ đầu”, trong đó chuỗi chuyển sang chế độ mà nó vẫn ở trên bộ xử lý cho đến khi hoàn thành công việc. Hầu hết các lần chờ phủ đầu là khi một luồng thực hiện cuộc gọi bên ngoài SQL Server (ví dụ:để lấy thông tin bảo mật từ Bộ điều khiển miền), nhưng đôi khi một luồng đang thực hiện điều gì đó bên trong SQL Server và cần hoàn thành nó trước khi có khả năng bị buộc phải nhường bộ xử lý bởi vì lượng tử luồng 4ms của nó đã hết hạn. Cả hai điều đó đều không phải là những gì đang xảy ra ở đây. Trong trường hợp này, chuỗi ghi lại thời điểm bắt đầu chờ đợi trước với kiểu chờ mới và sau đó cập nhật thống kê, có thể phát sinh các lần chờ * thực * khác như PAGEIOLATCH_SH trong quá trình thực hiện. Phải đến khi cập nhật thống kê hoàn tất thì thời gian chờ đợi trước mới kết thúc và được tính vào chỉ số thống kê chờ.

Tại sao điều này là một vấn đề lớn? Vâng, DMV sys.dm_os_waiting_tasks hiển thị các kiểu chờ cho tất cả các chuỗi đang * thực sự * đang chờ, tức là trên danh sách nhiệm vụ chờ của bộ lập lịch, vì vậy nếu chuỗi cập nhật thống kê đồng bộ không đợi WAIT_ON_SYNCHRONOUS_STATISTICS_UPDATE, thì kiểu chờ đó sẽ không hiển thị trong đầu ra của DMV. Không thể sử dụng kiểu chờ mới để xem liệu một truy vấn hiện đang chờ cập nhật thống kê.

Bạn có thể dễ dàng chứng minh điều này cho chính mình bằng cách làm như sau:

  • Tạo một bảng với vài trăm nghìn hàng
  • Tạo thống kê trên một cột của bảng và chỉ định FULLSCAN và PERSIST_SAMPLE_PERCENT =ON làm tùy chọn, buộc toàn bộ bảng phải được đọc mỗi khi thống kê được cập nhật
  • Cập nhật hai mươi nghìn hàng
  • Kiểm tra cơ sở dữ liệu và thực thi DBCC DROPCLEANBUFFERS
  • Thực hiện câu lệnh SELECT với mệnh đề WHERE trên cột có thống kê bạn đã tạo
  • Tìm trong sys.dm_os_waiting_tasks DMV để tìm ID phiên của SELECT và bạn sẽ thấy nó có thể đang đợi PAGEIOLATCH_SH khi cập nhật thống kê đọc qua bảng

Bỏ nỗi thất vọng đó sang một bên, có một mẹo để có thể xem liệu truy vấn có đang chờ cập nhật thống kê đồng bộ hay không. Khi cập nhật thống kê xảy ra, lệnh có tên STATMAN sẽ chạy và bạn có thể thấy lệnh này xảy ra trong đầu ra từ sys.dm_exec_requests :tình trạng trạng thái sẽ bị “tạm ngưng” (ngay cả khi chuỗi đang chạy, như tôi đã mô tả ở trên) và lệnh sẽ là “CHỌN (STATMAN).”

Loại Chờ Mới Có Công Dụng Gì?

Mặc dù kiểu chờ mới không thể được sử dụng như một cách ngay lập tức để cho biết truy vấn đang chờ cập nhật thống kê đồng bộ, nếu nó xuất hiện trong phân tích thống kê chờ thông thường của bạn, bạn biết một số truy vấn trong khối lượng công việc có thể bị chậm trễ này . Nhưng đó là giới hạn về tính hữu dụng của nó theo như tôi nghĩ. Trừ khi thời gian chờ trung bình hiển thị dưới dạng tỷ lệ phần trăm liên quan đến thời gian thực hiện truy vấn trung bình của bạn hoặc bạn liên tục nắm bắt các lần đợi trong một khoảng thời gian nhỏ để cho phép phân tích thích hợp, bạn không biết chắc liệu có sự cố hay không.

Đây là kiểu chờ trong đó thời gian chờ có thể thay đổi rất nhiều, tùy thuộc vào các yếu tố tôi đã đề cập trước đó. Do đó, tôi sẽ chỉ sử dụng sự hiện diện của loại chờ này để được cảnh báo về các sự cố tiềm ẩn và tôi muốn triển khai phiên Sự kiện mở rộng như được mô tả ở trên để nắm bắt các trường hợp cập nhật thống kê đồng bộ để xem liệu thời lượng của chúng có đủ dài để xứng đáng hay không thực hiện một số hành động sửa chữa.

Tóm tắt

Tôi không chắc rằng việc bổ sung loại chờ WAIT_ON_SYNCHRONOUS_STATISTICS_UPDATE sẽ thay đổi việc mọi người định cấu hình cập nhật thống kê không đồng bộ hay chỉ đơn giản là tự mình thực hiện tất cả các thống kê, nhưng ít nhất bây giờ bạn sẽ có thể biết liệu các truy vấn đang chờ thống kê đồng bộ cập nhật và thực hiện thêm một số hành động.

Cho đến lần sau, chúc bạn khắc phục sự cố hiệu suất!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Toán tử SQL không bằng với () cho người mới bắt đầu

  2. Tạo máy chủ được liên kết ODBC mà không cần định cấu hình nguồn dữ liệu

  3. Kết nối PolyBase với Salesforce.com

  4. Cách kiểm tra xem T-SQL UDF có bị ràng buộc bởi giản đồ hay không (Ngay cả khi nó được mã hóa)

  5. Cách xóa khoảng trắng ở đầu và / hoặc ở cuối của một chuỗi trong T-SQL