Lý lịch
Tôi có một truy vấn chạy với SQL Server 2008 R2 tham gia và / hoặc tham gia trái khoảng 12 "bảng" khác nhau. Cơ sở dữ liệu khá lớn với nhiều bảng trên 50 triệu hàng và khoảng 300 bảng khác nhau. Đó là cho một công ty lớn có 10 kho trên toàn quốc. Tất cả các kho đọc và ghi vào cơ sở dữ liệu. Vì vậy, nó khá lớn và khá bận rộn.
Truy vấn tôi gặp rắc rối với giao diện giống như thế này:
select t1.something, t2.something, etc.
from Table1 t1
inner join Table2 t2 on t1.id = t2.t1id
left outer join (select * from table 3) t3 on t3.t1id = t1.t1id
[etc]...
where t1.something = 123
Lưu ý rằng một trong các phép nối nằm trên truy vấn con không tương quan.
Vấn đề là bắt đầu từ sáng nay, không có bất kỳ thay đổi nào (mà tôi hoặc bất kỳ ai trong nhóm của tôi biết) đối với hệ thống, truy vấn thường mất khoảng 2 phút để chạy, bắt đầu mất một tiếng rưỡi để chạy - khi nó chạy chạy hết rồi. Phần còn lại của cơ sở dữ liệu là tốt. Tôi đã đưa truy vấn này ra khỏi chuỗi mà nó thường chạy và tôi đã chạy nó trong SSMS với các biến tham số được mã hóa cứng với cùng độ chậm.
Điều kỳ lạ là khi tôi lấy truy vấn phụ không tương quan và ném nó vào bảng tạm thời, sau đó sử dụng truy vấn đó thay cho truy vấn phụ, truy vấn sẽ chạy tốt. Ngoài ra (và đây là điều kỳ lạ nhất đối với tôi) nếu tôi thêm đoạn mã này vào cuối truy vấn, truy vấn sẽ chạy rất tốt:
and t.name like '%'
Tôi đã kết luận (có lẽ không chính xác) từ những thử nghiệm nhỏ này rằng lý do chậm lại là do cách thiết lập kế hoạch thực thi được lưu trong bộ nhớ cache của SQL - khi truy vấn hơi khác một chút, nó phải tạo một kế hoạch thực hiện mới.
Câu hỏi của tôi là: Khi một truy vấn được sử dụng để chạy nhanh đột nhiên bắt đầu chạy chậm vào giữa đêm và không có gì khác bị ảnh hưởng ngoại trừ một truy vấn này, làm cách nào để khắc phục sự cố này và làm thế nào để tôi không xảy ra trong tương lai ? Làm cách nào để biết SQL đang làm gì bên trong để làm cho nó chậm như vậy (nếu truy vấn xấu chạy, tôi có thể nhận được kế hoạch thực hiện nhưng nó sẽ không chạy - có lẽ kế hoạch thực hiện dự kiến sẽ cung cấp cho tôi thứ gì đó?)? Nếu vấn đề này xảy ra với kế hoạch thực hiện, làm cách nào để SQL không nghĩ rằng các kế hoạch thực hiện thực sự nhảm nhí là một ý tưởng tốt?
Ngoài ra, đây không phải là một vấn đề với việc đánh hơi tham số. Tôi đã thấy điều đó trước đây, và đây không phải là nó, vì ngay cả khi tôi mã hóa các biến đổi trong SSMS, tôi vẫn nhận được hiệu suất chậm.