Tôi có một truy vấn SQL Server 2008 hơi phức tạp (khoảng 200 dòng SQL khá dày đặc) không hoạt động khi tôi cần. Theo thời gian, hiệu suất giảm từ khoảng 0,5 giây xuống còn khoảng 2 giây.
Nhìn vào kế hoạch thực hiện, có một điều khá rõ ràng là bằng cách sắp xếp lại các phép nối, hiệu suất có thể được cải thiện. Tôi đã làm, và nó đã ... xuống còn khoảng 3 giây. Bây giờ truy vấn có gợi ý "LỰA CHỌN LỰA CHỌN LỰA CHỌN" và cuộc sống rất tốt.
Hôm nay tôi đến, dọn dẹp cơ sở dữ liệu. Tôi lưu trữ khoảng 20% các hàng, không thực hiện hành động nào trong cơ sở dữ liệu có liên quan ngoại trừ xóa các hàng ... kế hoạch thực hiện được HOÀN TOÀN hos . Nó hoàn toàn đánh giá sai có bao nhiêu hàng cây con nhất định sẽ trả về và (ví dụ) thay thế một:
<Hash>
với
<NestedLoops Optimized='false' WithUnorderedPrefetch='true'>
Bây giờ thời gian truy vấn tăng đột biến từ khoảng .3 giây đến khoảng 18 giây. (!) Chỉ vì tôi đã xóa hàng. Nếu tôi xóa gợi ý truy vấn, tôi sẽ quay lại khoảng 2 giây thời gian truy vấn. Tốt hơn, nhưng tồi tệ hơn.
Tôi đã tái tạo vấn đề sau khi khôi phục cơ sở dữ liệu tới nhiều vị trí và máy chủ. Chỉ cần xóa khoảng 20% số hàng từ mỗi bảng luôn gây ra sự cố này.
- Đây có phải là bình thường đối với một lệnh tham gia bắt buộc để làm cho các ước tính truy vấn hoàn toàn không chính xác (và do đó thời gian truy vấn không thể đoán trước)?
- Tôi có nên hy vọng rằng tôi sẽ phải chấp nhận hiệu suất truy vấn tối ưu phụ hay xem nó như một con chim ưng và thường xuyên chỉnh sửa gợi ý truy vấn không? Hoặc có thể gợi ý mỗi tham gia là tốt? .3s đến 2s là một thành công lớn.
- Rõ ràng là tại sao trình tối ưu hóa lại nổ tung sau khi xóa các hàng? Ví dụ: "có, nó đã quét mẫu và vì tôi đã lưu trữ hầu hết các hàng trước đó trong lịch sử dữ liệu, mẫu mang lại kết quả thưa thớt, vì vậy nó đánh giá thấp sự cần thiết của thao tác băm được sắp xếp"?
Nếu bạn muốn xem kế hoạch thực hiện, vui lòng đề xuất một vị trí tôi có thể đăng chúng. Mặt khác, tôi đã lấy mẫu bit tuyệt vời nhất. Đây là ước tính sai cơ bản, các số trong parens là các hàng (ước tính: thực tế).
/ Clustered Index Scan (908:7229)
Nested Loops (Inner Join) --<
\ NonClustered Index Seek (1:7229)
Lưu ý vòng lặp bên trong dự kiến sẽ quét 908 hàng, nhưng thay vào đó quét 52.258.441. Nếu nó là chính xác, chi nhánh này sẽ chạy khoảng 2ms, thay vì 12 giây. Trước khi xóa các hàng, ước tính tham gia bên trong này chỉ bị tắt bởi tổng hệ số là 2 và được thực hiện dưới dạng khớp băm trên hai chỉ mục được nhóm.