Trong một số bài đăng của tôi trong năm ngoái, tôi đã sử dụng chủ đề mọi người nhìn thấy một kiểu chờ đợi cụ thể và sau đó phản ứng theo kiểu “đầu gối tay ấp” với sự chờ đợi ở đó. Thông thường, điều này có nghĩa là làm theo một số lời khuyên kém trên Internet và thực hiện một hành động quyết liệt, không phù hợp hoặc đi đến kết luận về nguyên nhân gốc rễ của vấn đề là gì và sau đó lãng phí thời gian và công sức cho một cuộc rượt đuổi ngỗng hoang.
Một trong những kiểu chờ đợi mà phản ứng giật đầu gối diễn ra mạnh mẽ nhất và ở đó một số lời khuyên kém cỏi nhất tồn tại, đó là đợi CXPACKET. Đây cũng là kiểu chờ đợi phổ biến nhất trên máy chủ của mọi người (theo hai cuộc khảo sát về kiểu chờ lớn của tôi từ năm 2010 và 2014 - xem tại đây để biết chi tiết), vì vậy tôi sẽ đề cập đến nó trong bài đăng này.
Kiểu chờ CXPACKET có nghĩa là gì?
Giải thích đơn giản nhất là CXPACKET có nghĩa là bạn có các truy vấn chạy song song và bạn sẽ * luôn * thấy CXPACKET đang đợi một truy vấn song song. CXPACKET chờ đợi KHÔNG có nghĩa là bạn có vấn đề song song - bạn cần phải tìm hiểu sâu hơn để xác định điều đó.
Là một ví dụ về toán tử song song, hãy xem xét toán tử Luồng phân vùng lại, có biểu tượng sau trong kế hoạch truy vấn đồ họa:
Và đây là hình ảnh cho thấy những gì đang diễn ra về các chuỗi song song cho toán tử này, với mức độ song song (DOP) bằng 4:
Đối với DOP =4, sẽ có bốn luồng sản xuất, lấy dữ liệu từ trước đó trong kế hoạch truy vấn, dữ liệu sau đó sẽ quay trở lại phần còn lại của kế hoạch truy vấn thông qua bốn luồng tiêu dùng.
Bạn có thể thấy các chuỗi khác nhau trong toán tử song song đang chờ tài nguyên bằng cách sử dụng sys.dm_os_waiting_tasks DMV, trong execute_context_id cột (bài đăng này có kịch bản của tôi để thực hiện việc này).
Luôn luôn có một luồng 'điều khiển' cho bất kỳ kế hoạch song song nào, do tình cờ lịch sử luôn là luồng ID 0. Luồng điều khiển luôn đăng ký một thời gian chờ CXPACKET, với khoảng thời gian bằng khoảng thời gian kế hoạch cần để thực thi. Paul White có một lời giải thích tuyệt vời về các chủ đề trong các kế hoạch song song tại đây.
Thời gian duy nhất các luồng không điều khiển sẽ đăng ký CXPACKET chờ là nếu chúng hoàn thành trước các luồng khác trong toán tử. Điều này có thể xảy ra nếu một trong các luồng bị kẹt khi chờ tài nguyên trong một thời gian dài, vì vậy hãy xem kiểu chờ của luồng không hiển thị CXPACKET (sử dụng tập lệnh của tôi ở trên) và khắc phục sự cố một cách thích hợp. Điều này cũng có thể xảy ra do sự phân bổ công việc bị lệch giữa các chuỗi và tôi sẽ đi sâu hơn về trường hợp đó trong bài đăng tiếp theo của tôi ở đây (nguyên nhân là do thống kê lỗi thời và các vấn đề ước tính bản số khác).
Lưu ý rằng trong SQL Server 2016 SP2 và SQL Server 2017 RTM CU3, các luồng khách hàng không còn đăng ký CXPACKET chờ đợi. Họ đăng ký các đợi CXCONSUMER, rất lành tính và có thể được bỏ qua. Điều này là để giảm số lượng CXPACKET chờ được tạo và những cái còn lại có nhiều khả năng có thể thực hiện được hơn.
Tính song song không mong muốn?
Cho rằng CXPACKET chỉ đơn giản có nghĩa là bạn đã có song song xảy ra, điều đầu tiên cần xem xét là liệu bạn có mong đợi tính song song cho truy vấn đang sử dụng nó hay không. Truy vấn của tôi sẽ cung cấp cho bạn ID nút kế hoạch truy vấn nơi xảy ra song song (nó lấy ra ID nút từ kế hoạch truy vấn XML nếu kiểu chờ của luồng là CXPACKET), vì vậy hãy tìm ID nút đó và xác định xem sự song song có hợp lý không .
Một trong những trường hợp phổ biến của song song không mong muốn là khi quá trình quét bảng xảy ra trong đó bạn đang mong đợi một lần quét hoặc tìm kiếm chỉ mục nhỏ hơn. Bạn sẽ thấy điều này trong kế hoạch truy vấn hoặc bạn sẽ thấy nhiều PAGEIOLATCH_SH chờ (được thảo luận chi tiết tại đây) cùng với CXPACKET chờ (một mẫu thống kê chờ cổ điển cần chú ý). Có nhiều nguyên nhân gây ra tình trạng quét bảng không mong muốn, bao gồm:
- Thiếu chỉ mục không phân biệt nên quét bảng là giải pháp thay thế duy nhất
- Thống kê lỗi thời nên Trình tối ưu hoá Truy vấn cho rằng quét bảng là phương pháp truy cập dữ liệu tốt nhất để sử dụng
- Chuyển đổi ngầm định, do kiểu dữ liệu không khớp giữa cột trong bảng và biến hoặc tham số, có nghĩa là không thể sử dụng chỉ mục không phân biệt
- Số học đang được thực hiện trên một cột của bảng thay vì một biến hoặc tham số, có nghĩa là không thể sử dụng chỉ mục không phân biệt
Trong tất cả những trường hợp này, giải pháp được quyết định bởi những gì bạn tìm thấy nguyên nhân gốc rễ.
Nhưng điều gì sẽ xảy ra nếu không có trường hợp gốc rõ ràng và truy vấn được coi là đủ đắt để đảm bảo một kế hoạch song song?
Ngăn chặn song song
Trong số những thứ khác, Trình tối ưu hóa truy vấn quyết định tạo kế hoạch truy vấn song song nếu gói nối tiếp có chi phí cao hơn cost threshold for parallelism
, một cài đặt sp_configure cho ví dụ. Ngưỡng chi phí cho tính song song (hoặc CTFP) được đặt thành năm theo mặc định, có nghĩa là một kế hoạch không cần phải quá đắt để kích hoạt việc tạo một kế hoạch song song.
Một trong những cách dễ nhất để ngăn chặn sự tồn tại song song không mong muốn là tăng CTFP lên một con số cao hơn nhiều, khi bạn đặt nó càng cao thì khả năng tạo ra các kế hoạch song song càng ít. Một số người ủng hộ việc đặt CTFP ở khoảng từ 25 đến 50, nhưng cũng như với tất cả các cài đặt có thể điều chỉnh, tốt nhất là thử nghiệm các giá trị khác nhau và xem điều gì phù hợp nhất với môi trường của bạn. Nếu bạn muốn thêm một chút về phương pháp có lập trình để giúp chọn giá trị CTFP tốt, Jonathan đã viết một bài đăng trên blog hiển thị một truy vấn để phân tích bộ nhớ cache của kế hoạch và tạo ra một giá trị được đề xuất cho CTFP. Ví dụ:chúng tôi có một ứng dụng khách có CTFP được đặt thành 200 và một ứng dụng khác được đặt thành tối đa - 32767 - như một cách ngăn chặn cưỡng bức bất kỳ sự song song nào.
Bạn có thể thắc mắc tại sao máy khách thứ hai phải sử dụng CTFP như một phương pháp búa tạ để ngăn chặn song song khi bạn nghĩ rằng họ có thể đơn giản đặt 'mức độ song song tối đa' (hoặc MAXDOP) của máy chủ thành 1. Chà, bất kỳ ai có bất kỳ mức độ quyền nào cũng có thể chỉ định gợi ý MAXDOP truy vấn và ghi đè cài đặt MAXDOP của máy chủ, nhưng không thể ghi đè CTFP.
Và đó là một phương pháp khác để hạn chế tính song song - đặt gợi ý MAXDOP cho truy vấn bạn không muốn thực hiện song song.
Bạn cũng có thể giảm cài đặt MAXDOP của máy chủ, nhưng đó là một giải pháp quyết liệt vì nó có thể ngăn mọi thứ sử dụng song song. Ngày nay, các máy chủ thường có khối lượng công việc hỗn hợp, chẳng hạn như với một số truy vấn OLTP và một số truy vấn báo cáo. Nếu bạn hạ thấp MAXDOP của máy chủ, bạn sẽ cản trở hiệu suất của các truy vấn báo cáo.
Giải pháp tốt hơn khi có khối lượng công việc hỗn hợp là sử dụng CTFP như tôi đã mô tả ở trên hoặc sử dụng Resource Governor (tôi e rằng chỉ dành cho Doanh nghiệp). Bạn có thể sử dụng Resource Governor để tách khối lượng công việc thành các nhóm khối lượng công việc, sau đó đặt MAX_DOP (dấu gạch dưới không phải là lỗi đánh máy) cho mỗi nhóm khối lượng công việc. Và điều tốt khi sử dụng Resource Governor là MAX_DOP không thể bị ghi đè bởi gợi ý truy vấn MAXDOP.
Tóm tắt
Đừng rơi vào bẫy khi nghĩ rằng CXPACKET tự động chờ có nghĩa là bạn đã có hiện tượng song song xấu xảy ra và chắc chắn không làm theo một số lời khuyên trên Internet mà tôi đã thấy về việc đóng sập máy chủ bằng cách đặt MAXDOP thành 1. Hãy dành thời gian để điều tra lý do tại sao bạn thấy CXPACKET chờ đợi và liệu đó có phải là thứ cần được giải quyết hay chỉ là phần tạo tác của khối lượng công việc đang chạy chính xác.
Về số liệu thống kê chờ chung có liên quan, bạn có thể tìm thêm thông tin về việc sử dụng chúng để khắc phục sự cố hiệu suất trong:
- Loạt bài đăng trên blog SQLskills của tôi, bắt đầu với số liệu thống kê Chờ hoặc vui lòng cho tôi biết nó bị ảnh hưởng ở đâu
- Thư viện Loại Chờ và Lớp Chốt của tôi tại đây
- Khóa học đào tạo trực tuyến Pluralsight của tôi SQL Server:Khắc phục sự cố về hiệu suất sử dụng thống kê chờ
- Cố vấn Hiệu suất SQL Sentry
Trong phần tiếp theo của loạt bài này, tôi sẽ thảo luận về tính song song lệch và cung cấp cho bạn một cách đơn giản để xem nó xảy ra. Cho đến lúc đó, chúc bạn khắc phục sự cố!