Tôi sẽ nói ngay từ đầu rằng câu hỏi của tôi / vấn đề trông giống như này trước đó, nhưng vì tôi không chắc chắn nếu nguyên nhân hoặc các thông tin bắt đầu là như nhau, tôi quyết định gửi câu hỏi của tôi với một số chi tiết.
Vấn đề trong tầm tay:
- vào một giờ lạ (gần cuối ngày làm việc), một cá thể sản xuất bắt đầu hành xử thất thường:
- CPU cao chẳng hạn (từ mức cơ bản ~ 30%, nó tăng lên gấp đôi và vẫn đang tăng lên)
- số lượng giao dịch / giây tăng lên (mặc dù tải ứng dụng không thấy bất kỳ thay đổi nào)
- tăng số phiên nhàn rỗi
- các sự kiện chặn lạ giữa các phiên không bao giờ hiển thị hành vi này (thậm chí đọc các phiên không được cam kết đã gây ra chặn)
- chờ đợi hàng đầu cho khoảng thời gian là chốt trang không ở vị trí số 1, với khóa chiếm vị trí thứ 2
Sự khảo sát ban đầu:
- sử dụng sp_whoIsActive, chúng tôi thấy rằng một truy vấn được thực thi bởi công cụ giám sát của chúng tôi quyết định chạy cực kỳ chậm và lấy rất nhiều CPU, điều mà trước đây không xảy ra;
- mức độ cô lập của nó đã được đọc không cam kết;
- chúng tôi đã xem xét kế hoạch mà chúng tôi thấy các con số lập dị: StatementEstRows = "3.86846e + 010" với khoảng 150 TB dữ liệu ước tính sẽ được trả về
- chúng tôi nghi ngờ tính năng giám sát truy vấn của công cụ giám sát là nguyên nhân, vì vậy chúng tôi đã vô hiệu hóa tính năng này (chúng tôi cũng đã mở một vé với nhà cung cấp của chúng tôi để kiểm tra xem họ có biết về bất kỳ vấn đề nào không)
- từ sự kiện đầu tiên đó, nó đã xảy ra thêm một vài lần nữa, với mỗi lần chúng ta giết phiên, mọi thứ trở lại bình thường;
- chúng tôi nhận thấy truy vấn cực kỳ giống với một trong những truy vấn được MS sử dụng trong giám sát BOL cho Truy vấn cửa hàng truy vấn - Các truy vấn gần đây đã hồi quy về hiệu suất (so sánh các thời điểm khác nhau)
- chúng tôi chạy cùng một truy vấn theo cách thủ công và thấy hành vi tương tự (CPU được sử dụng ngày càng tăng, chờ đợi chốt, khóa bất ngờ .. vv)
Truy vấn có tội:
Select qt.query_sql_text,
q.query_id,
qt.query_text_id,
rs1.runtime_stats_id AS runtime_stats_id_1,
interval_1 = DateAdd(minute, -(DateDiff(minute, getdate(), getutcdate())), rsi1.start_time),
p1.plan_id AS plan_1,
rs1.avg_duration AS avg_duration_1,
rs2.avg_duration AS avg_duration_2,
p2.plan_id AS plan_2,
interval_2 = DateAdd(minute, -(DateDiff(minute, getdate(), getutcdate())), rsi2.start_time),
rs2.runtime_stats_id AS runtime_stats_id_2
From sys.query_store_query_text AS qt
Inner Join sys.query_store_query AS q
ON qt.query_text_id = q.query_text_id
Inner Join sys.query_store_plan AS p1
ON q.query_id = p1.query_id
Inner Join sys.query_store_runtime_stats AS rs1
ON p1.plan_id = rs1.plan_id
Inner Join sys.query_store_runtime_stats_interval AS rsi1
ON rsi1.runtime_stats_interval_id = rs1.runtime_stats_interval_id
Inner Join sys.query_store_plan AS p2
ON q.query_id = p2.query_id
Inner Join sys.query_store_runtime_stats AS rs2
ON p2.plan_id = rs2.plan_id
Inner Join sys.query_store_runtime_stats_interval AS rsi2
ON rsi2.runtime_stats_interval_id = rs2.runtime_stats_interval_id
Where rsi1.start_time > DATEADD(hour, -48, GETUTCDATE())
AND rsi2.start_time > rsi1.start_time
AND p1.plan_id <> p2.plan_id
AND rs2.avg_duration > rs1.avg_duration * 2
Order By q.query_id, rsi1.start_time, rsi2.start_time
Cài đặt và thông tin:
- SQL Server 2016 SP1 CU4 Enterprise trên cụm Windows Server 2012R2
- Cửa hàng truy vấn được bật và định cấu hình như mặc định (không thay đổi cài đặt)
- cơ sở dữ liệu được nhập từ phiên bản SQL 2005 (và vẫn ở mức tương thích 100)
Quan sát thực nghiệm:
- do số liệu thống kê cực kỳ kỳ quặc, chúng tôi đã lấy tất cả các đối tượng * plan_persist ** được sử dụng trong kế hoạch ước tính xấu (chưa có kế hoạch thực tế, vì truy vấn không bao giờ kết thúc) và kiểm tra thống kê, một số chỉ mục được sử dụng trong kế hoạch không có bất kỳ thống kê nào (DBCC SHOWSTATISTICS không trả lại bất cứ điều gì, chọn từ sys.stats hiển thị hàm NULL stats_date () cho một số chỉ mục
Giải pháp nhanh và bẩn:
- tự tạo các thống kê bị thiếu trên các đối tượng hệ thống liên quan đến Kho lưu trữ truy vấn hoặc
- buộc truy vấn chạy bằng CE mới (trackflag) - cũng sẽ tạo / cập nhật các số liệu thống kê cần thiết hoặc
- thay đổi mức độ tương thích của cơ sở dữ liệu thành 130 (do đó, theo mặc định, nó sẽ sử dụng CE mới)
Vì vậy, câu hỏi thực sự của tôi sẽ là:
Tại sao một truy vấn trên Cửa hàng truy vấn sẽ gây ra vấn đề về hiệu suất trên toàn bộ phiên bản? Có phải chúng ta đang ở trong một lãnh thổ lỗi với Truy vấn Cửa hàng?
PS: Tôi sẽ tải lên một số tệp (màn hình in, số liệu thống kê và kế hoạch IO) trong một thời gian ngắn.
Các tập tin được thêm vào Dropbox .
Kế hoạch 1 - kế hoạch dự tính lập dị ban đầu trong sản xuất
Kế hoạch 2 - kế hoạch thực tế, CE cũ, trong một env thử nghiệm (cùng hành vi, cùng chỉ số lập dị)
Kế hoạch 3 - kế hoạch thực tế, CE mới, trong một thử nghiệm env