Nhiều người sử dụng thống kê thời gian chờ như một phần của phương pháp khắc phục sự cố hiệu suất tổng thể của họ, tôi cũng vậy, vì vậy câu hỏi mà tôi muốn khám phá trong bài đăng này là về các loại chờ liên quan đến chi phí quan sát. Theo chi phí của người quan sát, ý tôi là tác động đến thông lượng khối lượng công việc của SQL Server do SQL Profiler, dấu vết phía máy chủ hoặc các phiên Sự kiện mở rộng gây ra. Để biết thêm về chủ đề quan sát trên không, hãy xem hai bài đăng sau đây của đồng nghiệp Jonathan Kehayias của tôi :
- Đo lường "Chi phí của trình quan sát" của SQL Trace so với Sự kiện mở rộng
- Tác động của Sự kiện mở rộng query_post_execution_showplan trong SQL Server 2012
Vì vậy, trong bài đăng này, tôi muốn giới thiệu qua một vài biến thể của chi phí quan sát và xem liệu chúng ta có thể tìm thấy các kiểu chờ nhất quán liên quan đến sự suy giảm đo được hay không. Có nhiều cách mà người dùng SQL Server triển khai theo dõi trong môi trường sản xuất của họ, vì vậy kết quả của bạn có thể khác nhau, nhưng tôi muốn đề cập đến một số danh mục rộng và báo cáo lại những gì tôi tìm thấy:
- Sử dụng phiên SQL Profiler
- Sử dụng theo dõi phía máy chủ
- Sử dụng theo dõi phía máy chủ, ghi vào đường dẫn I / O chậm
- Sử dụng Sự kiện mở rộng với mục tiêu đệm vòng
- Sử dụng Sự kiện mở rộng với mục tiêu tệp
- Sử dụng Sự kiện mở rộng với mục tiêu tệp trên đường dẫn I / O chậm
- Sử dụng Sự kiện mở rộng với mục tiêu tệp trên đường dẫn I / O chậm mà không bị mất sự kiện
Bạn có thể nghĩ ra các biến thể khác về chủ đề và tôi mời bạn chia sẻ bất kỳ phát hiện thú vị nào về số liệu thống kê về chi phí quan sát và thời gian chờ đợi dưới dạng nhận xét trong bài đăng này.
Đường cơ sở
Đối với thử nghiệm, tôi đã sử dụng một máy ảo VMware với bốn vCPU và 4GB RAM. Khách máy ảo của tôi đã sử dụng ổ SSD OCZ Vertex. Hệ điều hành là Windows Server 2008 R2 Enterprise và phiên bản của SQL Server là 2012, SP1 CU4.
Đối với “khối lượng công việc”, tôi đang sử dụng truy vấn chỉ đọc trong một vòng lặp với cơ sở dữ liệu mẫu Tín dụng năm 2008, được đặt thành ĐI 10.000.000 lần.
USE [Credit]; GO SELECT TOP 1 [member].[member_no], [member].[lastname], [payment].[payment_no], [payment].[payment_dt], [payment].[payment_amt] FROM [dbo].[payment] INNER JOIN [dbo].[member] ON [member].[member_no] = [payment].[member_no]; GO 10000000
Tôi cũng đang thực hiện truy vấn này qua 16 phiên đồng thời. Kết quả cuối cùng trên hệ thống thử nghiệm của tôi là sử dụng 100% CPU trên tất cả các vCPU trên khách ảo và trung bình 14.492 yêu cầu hàng loạt mỗi giây trong khoảng thời gian 2 phút.
Về việc theo dõi sự kiện, trong mỗi bài kiểm tra, tôi đã sử dụng Showplan XML Statistics Profile
cho SQL Profiler và kiểm tra theo dõi phía máy chủ - và query_post_execution_showplan
cho các phiên Sự kiện mở rộng. Các sự kiện kế hoạch thực thi rất đắt, đó chính là lý do tại sao tôi chọn chúng để tôi có thể xem liệu trong những trường hợp khắc nghiệt, liệu tôi có thể lấy các chủ đề loại chờ hay không.
Để thử nghiệm tích lũy kiểu chờ trong một khoảng thời gian thử nghiệm, tôi đã sử dụng truy vấn sau. Không có gì lạ mắt - chỉ cần xóa số liệu thống kê, đợi 2 phút và sau đó thu thập 10 điểm tích lũy chờ đợi hàng đầu cho phiên bản SQL Server trong thời gian kiểm tra xuống cấp:
-- Clearing the wait stats DBCC SQLPERF('waitstats', clear); WAITFOR DELAY '00:02:00'; GO SELECT TOP 10 [wait_type], [waiting_tasks_count], [wait_time_ms] FROM sys.[dm_os_wait_stats] AS [ws] ORDER BY [wait_time_ms] DESC;
Lưu ý rằng tôi không lọc ra các kiểu chờ trong nền thường được lọc ra và điều này là do tôi không muốn loại bỏ thứ gì đó bình thường lành tính - nhưng trong trường hợp này, thực sự chỉ ra một khu vực thực tế để điều tra thêm.
Phiên hồ sơ SQL
Bảng sau đây hiển thị các yêu cầu hàng loạt trước và sau mỗi giây khi bật theo dõi theo dõi SQL Profiler cục bộ Showplan XML Statistics Profile
(chạy trên cùng một máy ảo với phiên bản SQL Server):
Yêu cầu hàng loạt cơ sở mỗi giây (trung bình 2 phút) | Yêu cầu hàng loạt phiên của trình biên dịch SQL mỗi giây (trung bình 2 phút) |
---|---|
14.492 | 1,416 |
Bạn có thể thấy rằng theo dõi SQL Profiler làm giảm thông lượng đáng kể.
Đối với thời gian chờ tích lũy trong cùng khoảng thời gian đó, các kiểu chờ hàng đầu như sau (như với phần còn lại của các bài kiểm tra trong bài viết này, tôi đã thực hiện một vài lần chạy thử nghiệm và kết quả nói chung là nhất quán):
wait_type | wait_tasks_count | wait_time_ms |
---|---|---|
TRACEWRITE | 67.142 | 1.149.824 |
FT_IFTS_SCHEDULER_IDLE_WAIT | 4 | 237.003 |
SLEEP_TASK | 313 | 180.449 |
REQUEST_FOR_DEADLOCK_SEARCH | 24 | 120,111 |
HADR_FILESTREAM_IOMGR_IOCOMPLETION | 240 | 120.086 |
LAZYWRITER_SLEEP | 120 | 120.059 |
DIRTY_PAGE_POLL | 1.198 | 120.038 |
HADR_WORK_QUEUE | 12 | 120.015 |
LOGMGR_QUEUE | 937 | 120.011 |
SQLTRACE_INCREMENTAL_FLUSH_SLEEP | 30 | 120.006 |
Kiểu chờ đợi nảy ra với tôi là TRACEWRITE
- được Books Online định nghĩa là kiểu chờ đợi “xảy ra khi nhà cung cấp theo dõi tập hợp hàng SQL Trace đợi một bộ đệm miễn phí hoặc bộ đệm có các sự kiện để xử lý”. Phần còn lại của các kiểu chờ trông giống như kiểu chờ trong nền tiêu chuẩn mà một kiểu thường sẽ lọc ra khỏi tập kết quả của bạn. Hơn nữa, tôi đã nói về một vấn đề tương tự với việc theo dõi quá mức trong một bài báo vào năm 2011 có tên là Observer overhead - mối nguy hiểm của việc theo dõi quá nhiều - vì vậy tôi đã quen với kiểu chờ đợi này đôi khi chỉ đúng các vấn đề trên không của người quan sát. Bây giờ trong trường hợp cụ thể mà tôi đã viết blog, đó không phải là SQL Profiler mà là một ứng dụng khác sử dụng nhà cung cấp theo dõi tập hợp hàng (không hiệu quả).
Theo dõi phía máy chủ
Đó là đối với SQL Profiler, nhưng còn về chi phí theo dõi phía máy chủ thì sao? Bảng sau đây cho thấy các yêu cầu hàng loạt trước và sau mỗi giây khi cho phép ghi dấu vết phía máy chủ cục bộ vào tệp:
Yêu cầu hàng loạt cơ sở mỗi giây (trung bình 2 phút) | Yêu cầu hàng loạt của trình biên dịch SQL mỗi giây (trung bình 2 phút) |
---|---|
14.492 | 4.015 |
Các kiểu chờ đợi hàng đầu như sau (Tôi đã chạy thử một vài lần và kết quả đầu ra là nhất quán):
wait_type | wait_tasks_count | wait_time_ms |
---|---|---|
FT_IFTS_SCHEDULER_IDLE_WAIT | 4 | 237.015 |
SLEEP_TASK | 253 | 180.871 |
SQLTRACE_INCREMENTAL_FLUSH_SLEEP | 30 | 120.046 |
HADR_WORK_QUEUE | 12 | 120.042 |
REQUEST_FOR_DEADLOCK_SEARCH | 24 | 120.021 |
XE_DISPATCHER_WAIT | 3 | 120.006 |
CHỜ ĐỢI | 1 | 120.000 |
LOGMGR_QUEUE | 931 | 119.993 |
DIRTY_PAGE_POLL | 1.193 | 119,958 |
XE_TIMER_EVENT | 55 | 119,954 |
Lần này, chúng tôi không thấy TRACEWRITE
(chúng tôi hiện đang sử dụng nhà cung cấp tệp) và kiểu chờ liên quan đến dấu vết khác, SQLTRACE_INCREMENTAL_FLUSH_SLEEP
không có giấy tờ tăng lên - nhưng so với thử nghiệm đầu tiên, có thời gian chờ tích lũy rất giống nhau (120.046 so với 120.006) - và đồng nghiệp của tôi Erin Stellato (@erinstellato) đã nói về kiểu chờ cụ thể này trong bài đăng của cô ấy Tìm hiểu khi thống kê chờ được xóa lần cuối . Vì vậy, nhìn vào các kiểu chờ đợi khác, không có kiểu chờ nào được coi là lá cờ đỏ đáng tin cậy.
Ghi dấu vết phía máy chủ vào đường dẫn I / O chậm
Điều gì sẽ xảy ra nếu chúng ta đặt tệp theo dõi phía máy chủ trên đĩa chậm? Bảng sau đây hiển thị các yêu cầu hàng loạt trước và sau mỗi giây khi bật theo dõi phía máy chủ cục bộ ghi vào tệp trên thẻ USB:
Yêu cầu hàng loạt cơ sở mỗi giây (trung bình 2 phút) | Yêu cầu hàng loạt của trình biên dịch SQL mỗi giây (trung bình 2 phút) |
---|---|
14.492 | 260 |
Như chúng ta có thể thấy - hiệu suất bị giảm sút đáng kể - ngay cả so với thử nghiệm trước đó.
Các kiểu chờ đợi hàng đầu như sau:
wait_type | wait_tasks_count | wait_time_ms |
---|---|---|
SQLTRACE_FILE_BUFFER | 357 | 351.174 |
SP_SERVER_DIAGNOSTICS_SLEEP | 2.273 | 299.995 |
SLEEP_TASK | 240 | 194,264 |
FT_IFTS_SCHEDULER_IDLE_WAIT | 2 | 181.458 |
REQUEST_FOR_DEADLOCK_SEARCH | 25 | 125.007 |
LAZYWRITER_SLEEP | 63 | 124.437 |
LOGMGR_QUEUE | 941 | 120.559 |
HADR_FILESTREAM_IOMGR_IOCOMPLETION | 67 | 120.516 |
CHỜ ĐỢI | 1 | 120.515 |
DIRTY_PAGE_POLL | 1.204 | 120.513 |
Một kiểu chờ xuất hiện cho bài kiểm tra này là SQLTRACE_FILE_BUFFER
không có giấy tờ . Không có nhiều tài liệu về vấn đề này, nhưng dựa vào tên, chúng tôi có thể đưa ra phỏng đoán có học thức (đặc biệt là dựa trên cấu hình của bài kiểm tra cụ thể này).
Sự kiện mở rộng tới mục tiêu bộ đệm vòng
Tiếp theo, chúng ta hãy xem xét các phát hiện về phiên Sự kiện mở rộng tương đương. Tôi đã sử dụng định nghĩa phiên sau:
CREATE EVENT SESSION [ApplicationXYZ] ON SERVER ADD EVENT sqlserver.query_post_execution_showplan, ADD TARGET package0.ring_buffer(SET max_events_limit=(1000)) WITH (STARTUP_STATE=ON); GO
Bảng sau đây cho thấy các yêu cầu hàng loạt trước và sau mỗi giây khi bật phiên XE với mục tiêu bộ đệm vòng (nắm bắt query_post_execution_showplan
sự kiện):
Yêu cầu hàng loạt cơ sở mỗi giây (trung bình 2 phút) | Yêu cầu hàng loạt của trình biên dịch SQL mỗi giây (trung bình 2 phút) |
---|---|
14.492 | 4,737 |
Các kiểu chờ đợi hàng đầu như sau:
wait_type | wait_tasks_count | wait_time_ms |
---|---|---|
SP_SERVER_DIAGNOSTICS_SLEEP | 612 | 299.992 |
FT_IFTS_SCHEDULER_IDLE_WAIT | 4 | 237.006 |
SLEEP_TASK | 240 | 181.739 |
LAZYWRITER_SLEEP | 120 | 120.219 |
HADR_WORK_QUEUE | 12 | 120.038 |
DIRTY_PAGE_POLL | 1.198 | 120.035 |
REQUEST_FOR_DEADLOCK_SEARCH | 24 | 120.017 |
SQLTRACE_INCREMENTAL_FLUSH_SLEEP | 30 | 120.011 |
LOGMGR_QUEUE | 936 | 120.008 |
CHỜ ĐỢI | 1 | 120.001 |
Không có gì xuất hiện liên quan đến XE, chỉ có tác vụ nền "nhiễu".
Sự kiện mở rộng đến mục tiêu tệp
Điều gì về việc thay đổi phiên để sử dụng mục tiêu tệp thay vì mục tiêu bộ đệm vòng? Bảng sau đây cho thấy các yêu cầu hàng loạt trước và sau mỗi giây khi bật phiên XE với mục tiêu tệp thay vì mục tiêu bộ đệm vòng:
Yêu cầu hàng loạt cơ sở mỗi giây (trung bình 2 phút) | Yêu cầu hàng loạt của trình biên dịch SQL mỗi giây (trung bình 2 phút) |
---|---|
14.492 | 4.299 |
Các kiểu chờ đợi hàng đầu như sau:
wait_type | wait_tasks_count | wait_time_ms |
---|---|---|
SP_SERVER_DIAGNOSTICS_SLEEP | 2.103 | 299.996 |
FT_IFTS_SCHEDULER_IDLE_WAIT | 4 | 237.003 |
SLEEP_TASK | 253 | 180.663 |
LAZYWRITER_SLEEP | 120 | 120.187 |
HADR_WORK_QUEUE | 12 | 120.029 |
SQLTRACE_INCREMENTAL_FLUSH_SLEEP | 30 | 120.019 |
REQUEST_FOR_DEADLOCK_SEARCH | 24 | 120.011 |
CHỜ ĐỢI | 1 | 120.001 |
XE_TIMER_EVENT | 59 | 119,966 |
LOGMGR_QUEUE | 935 | 119,957 |
Không có gì, ngoại trừ XE_TIMER_EVENT
, nhảy ra với tư cách liên quan đến XE. Bob Ward’s Wait Type Repository đề cập đến điều này là an toàn để bỏ qua trừ khi có điều gì đó có thể xảy ra sai - nhưng trên thực tế, bạn có nhận thấy kiểu chờ thường lành tính này nếu nó ở vị trí thứ 9 trên hệ thống của bạn trong quá trình giảm hiệu suất không? Và điều gì sẽ xảy ra nếu bạn đang lọc nó vì tính chất bình thường lành tính của nó?
Sự kiện mở rộng đến mục tiêu tệp đường dẫn I / O chậm
Bây giờ điều gì sẽ xảy ra nếu tôi đặt tệp trên đường dẫn I / O chậm? Bảng sau đây hiển thị các yêu cầu hàng loạt trước và sau mỗi giây khi bật phiên XE với mục tiêu tệp trên thanh USB:
Yêu cầu hàng loạt cơ sở mỗi giây (trung bình 2 phút) | Yêu cầu hàng loạt của trình biên dịch SQL mỗi giây (trung bình 2 phút) |
---|---|
14.492 | 4.386 |
Các kiểu chờ đợi hàng đầu như sau:
wait_type | wait_tasks_count | wait_time_ms |
---|---|---|
FT_IFTS_SCHEDULER_IDLE_WAIT | 4 | 237.046 |
SLEEP_TASK | 253 | 180.719 |
HADR_FILESTREAM_IOMGR_IOCOMPLETION | 240 | 120.427 |
LAZYWRITER_SLEEP | 120 | 120.190 |
HADR_WORK_QUEUE | 12 | 120.025 |
SQLTRACE_INCREMENTAL_FLUSH_SLEEP | 30 | 120.013 |
REQUEST_FOR_DEADLOCK_SEARCH | 24 | 120.011 |
CHỜ ĐỢI | 1 | 120.002 |
DIRTY_PAGE_POLL | 1.197 | 119,977 |
XE_TIMER_EVENT | 59 | 119,949 |
Một lần nữa, không có gì liên quan đến XE xuất hiện ngoại trừ XE_TIMER_EVENT
.
Sự kiện mở rộng đến mục tiêu tệp đường dẫn I / O chậm, không mất sự kiện
Bảng sau đây hiển thị các yêu cầu hàng loạt trước và sau mỗi giây khi bật phiên XE với mục tiêu tệp trên thẻ USB, nhưng lần này không cho phép mất sự kiện (EVENT_RETENTION_MODE =NO_EVENT_LOSS) - không được khuyến nghị và bạn sẽ thấy trong kết quả tại sao đó có thể là:
Yêu cầu hàng loạt cơ sở mỗi giây (trung bình 2 phút) | Yêu cầu hàng loạt của trình biên dịch SQL mỗi giây (trung bình 2 phút) |
---|---|
14.492 | 539 |
Các kiểu chờ đợi hàng đầu như sau:
wait_type | wait_tasks_count | wait_time_ms |
---|---|---|
XE_BUFFERMGR_FREEBUF_EVENT | 8.773 | 1.707.845 |
FT_IFTS_SCHEDULER_IDLE_WAIT | 4 | 237.003 |
SLEEP_TASK | 337 | 180.446 |
LAZYWRITER_SLEEP | 120 | 120.032 |
DIRTY_PAGE_POLL | 1.198 | 120.026 |
HADR_WORK_QUEUE | 12 | 120.009 |
REQUEST_FOR_DEADLOCK_SEARCH | 24 | 120.007 |
SQLTRACE_INCREMENTAL_FLUSH_SLEEP | 30 | 120.006 |
CHỜ ĐỢI | 1 | 120.000 |
XE_TIMER_EVENT | 59 | 119,944 |
Với mức giảm thông lượng cực đại, chúng tôi thấy XE_BUFFERMGR_FREEBUF_EVENT
nhảy lên vị trí số một trên kết quả thời gian chờ tích lũy của chúng tôi. Cái này là được ghi lại trong Books Online và Microsoft cho chúng tôi biết rằng sự kiện này được liên kết với các phiên XE được định cấu hình để không mất sự kiện và nơi tất cả các bộ đệm trong phiên đã đầy.
Tác động của Người quan sát
Chờ các loại sang một bên, thật thú vị khi lưu ý tác động của mỗi phương pháp quan sát đến khả năng xử lý yêu cầu hàng loạt của khối lượng công việc của chúng tôi:
Tác động của các phương pháp quan sát khác nhau đến các yêu cầu hàng loạt mỗi giây
Đối với tất cả các phương pháp tiếp cận, có một tác động đáng kể - nhưng không gây sốc - so với đường cơ sở của chúng tôi (không quan sát); Tuy nhiên, bạn cảm thấy khó khăn nhất khi sử dụng Profiler, khi sử dụng Server-Side Trace đến đường dẫn I / O chậm hoặc Sự kiện mở rộng đến mục tiêu tệp trên đường dẫn I / O chậm - nhưng chỉ khi được định cấu hình để không mất sự kiện. Với việc mất sự kiện, thiết lập này thực sự hoạt động ngang bằng với mục tiêu tệp đến đường dẫn I / O nhanh, có lẽ vì nó có thể giảm nhiều sự kiện hơn.
Tóm tắt
Tôi đã không kiểm tra mọi tình huống có thể xảy ra và chắc chắn có những kết hợp thú vị khác (chưa kể đến các hành vi khác nhau dựa trên phiên bản SQL Server), nhưng kết luận quan trọng mà tôi rút ra từ khám phá này là bạn không phải lúc nào cũng dựa vào tích lũy kiểu chờ rõ ràng con trỏ khi đối mặt với một kịch bản trên cao của người quan sát. Dựa trên các bài kiểm tra trong bài đăng này, chỉ có ba trong số bảy trường hợp biểu hiện một kiểu chờ đợi cụ thể có thể giúp bạn đi đúng hướng. Ngay cả khi đó - những bài kiểm tra này vẫn diễn ra trên một hệ thống được kiểm soát - và đôi khi mọi người lọc ra các kiểu chờ đợi nói trên dưới dạng các kiểu nền lành tính - vì vậy bạn có thể hoàn toàn không thấy chúng.
Với điều này, bạn có thể làm gì? Đối với sự suy giảm hiệu suất mà không có các triệu chứng rõ ràng hoặc rõ ràng, tôi khuyên bạn nên mở rộng phạm vi để hỏi về dấu vết và phiên XE (để tránh xa - tôi cũng khuyên bạn nên mở rộng phạm vi của mình nếu hệ thống bị ảo hóa hoặc có thể có các tùy chọn nguồn không chính xác). Ví dụ:như một phần của việc khắc phục sự cố hệ thống, hãy kiểm tra sys.[traces]
và sys.[dm_xe_sessions]
để xem có điều gì không mong muốn đang chạy trên hệ thống không. Nó là một lớp bổ sung cho những gì bạn cần lo lắng, nhưng thực hiện một vài xác thực nhanh chóng có thể giúp bạn tiết kiệm đáng kể thời gian.