Yêu cầu cấp bộ nhớ lớn


7

Tôi có một truy vấn với nhiều kế hoạch thực hiện, bộ nhớ được cấp cho một kế hoạch là rất lớn so với kế hoạch thứ hai

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

dựa trên bài viết này https://bloss.msdn.microsoft.com/sql_server_team/addressing-large-memory-grant-requests-from-optimized-nested-loops/

Sự cố xảy ra khi bảng ngoài của phép nối Nested Loop có một biến vị ngữ lọc kết quả thành một đầu vào nhỏ, nhưng sắp xếp theo lô có vẻ như đang sử dụng ước tính cho số lượng thẻ tương đương với toàn bộ bảng bên ngoài. Điều này có thể dẫn đến việc cấp bộ nhớ quá mức mà trong một máy chủ rất đồng thời có thể có một số tác dụng phụ, như điều kiện OOM, áp lực bộ nhớ cho việc xóa bộ nhớ cache của gói hoặc chờ đợi RESOURCE_SEMAPHORE. Chúng tôi đã thấy làm thế nào một truy vấn duy nhất phù hợp với mẫu này thực sự có thể nhận được vài GB bộ nhớ được cấp trên các máy cao cấp (1TB + RAM).

Một tùy chọn cho đến bây giờ sẽ là vô hiệu hóa tính năng này trên toàn cầu bằng cách sử dụng Trace Flag 2340, như được mô tả trong KB 2801413. Tuy nhiên, trong SQL Server 2016 RC0, chúng tôi đã thay đổi hành vi để duy trì lợi thế của tối ưu hóa, nhưng hiện tại giới hạn cấp tối đa được dựa trên trên không gian cấp bộ nhớ có sẵn. Cải tiến này cũng chuyển thành khả năng mở rộng tốt hơn, theo nghĩa có thể thực hiện nhiều truy vấn hơn với dung lượng bộ nhớ nhỏ hơn. Chúng tôi đang xem xét chuyển lại hành vi này sang hành vi sắp tới đã chuyển hành vi này sang SQL Server 2014 Service Pack 2 và như thường lệ cung cấp giá trị gia tăng cho các phiên bản trên thị trường.

Đây chính xác là những gì tôi đang thấy tuy nhiên tôi đang sử dụng SQL Server 2016 Enterprise.

Đây là những kế hoạch thực hiện

https://www.brentozar.com/pastetheplan/?id=SJ0mYAy0b

https://www.brentozar.com/pastetheplan/?id=BJzutC1R-

Câu hỏi của tôi là

  1. Lý do cho 2 kế hoạch thực hiện là gì?

  2. Trình tối ưu hóa đang sử dụng kế hoạch thực hiện hàng đầu, tôi buộc nó phải sử dụng kế hoạch thấp hơn nhưng sau đó đôi khi nó lại quay trở lại kế hoạch hàng đầu, lý do nào cho điều đó?

  3. Làm thế nào để khắc phục vấn đề này? Vấn đề này khiến ứng dụng bị sập (có nhiều RESOURCE_SEMAPHOREchờ đợi và ứng dụng trở nên không phản hồi)? Tôi nên sử dụng gợi ý: DISABLE_OPTIMIZED_NESTED_LOOPhay Trace Flag 2340?

    LƯU Ý: Tôi đã kiểm tra XML và cả hai gói đều có NestedLoops Optimized="false"

Câu trả lời:


7

1. Lý do cho 2 kế hoạch thực hiện là gì?

Từ tài liệu sys.query_context_sinstall (Transact-SQL) :

Có một số cài đặt ngữ cảnh có sẵn trong SQL Server có ảnh hưởng đến ngữ nghĩa truy vấn (xác định kết quả chính xác của truy vấn). Cùng một văn bản truy vấn được biên dịch theo các cài đặt khác nhau có thể tạo ra các kết quả khác nhau (tùy thuộc vào dữ liệu cơ bản).

Có vẻ như rất có thể văn bản truy vấn tương tự đã được gửi từ các phiên có cài đặt ngữ cảnh khác nhau. Xem thêm Chậm trong Ứng dụng, Nhanh trong SSMS? bởi Erland Sommarskog.

2. Trình tối ưu hóa đang sử dụng kế hoạch thực hiện hàng đầu, tôi buộc nó phải sử dụng kế hoạch thấp hơn nhưng sau đó đôi khi nó lại chuyển sang kế hoạch hàng đầu, lý do nào cho điều đó?

Các kế hoạch vẫn sẽ biên dịch lại theo thời gian dựa trên các quy tắc thông thường xung quanh các thay đổi để ví dụ như các đối tượng cơ bản, số liệu thống kê, lược đồ. Buộc một kế hoạch lưu trữ truy vấn giúp đảm bảo kế hoạch được sử dụng ít nhất sẽ tương tự về cơ bản với kế hoạch nguồn, như sys.query_store_plan (Transact-SQL) :

Cơ chế bắt buộc không đảm bảo rằng chính xác kế hoạch này sẽ được sử dụng cho truy vấn được tham chiếu bởi query_id . Kế hoạch buộc các truy vấn gây ra được biên dịch lại và thường tạo ra chính xác cùng hoặc kế hoạch tương tự với kế hoạch được tham chiếu bởi plan_id .

Mỗi (biên dịch lại) có thể tạo ra các gói với các ước tính khác nhau (bao gồm cấp bộ nhớ) tùy thuộc vào bất kỳ giá trị nào trong truy vấn hiển thị cho trình tối ưu hóa tại thời điểm biên dịch. Cấp bộ nhớ cụ thể không thể bị buộc sử dụng lưu trữ truy vấn hoặc hướng dẫn kế hoạch.

3. Làm thế nào để khắc phục vấn đề này?

Như câu trả lời của Dan Guzman cho thấy, nếu kế hoạch rất nhạy cảm với các giá trị tham số cụ thể, thì việc biên soạn một kế hoạch mới cho mỗi lần thực hiện bằng một OPTION (RECOMPILE)gợi ý có thể là giải pháp thực tế tốt nhất.

Điều đó nói rằng, có rất ít công cụ có sẵn để ảnh hưởng đến các kế hoạch thực hiện phía cập nhật, có thể phức tạp khi liên quan đến các khóa như khóa ngoại và các khung nhìn được lập chỉ mục. Nếu vẫn thất bại, bạn có thể thấy rằng một kế hoạch thực hiện mà không sắp xếp (để sắp xếp các hàng theo thứ tự khóa chỉ mục) tạo ra kết quả tốt nhất. Không có cách nào được ghi lại mà tôi biết để tạo ra các kế hoạch mà không có các loại này, nhưng bạn có thể thử buộc kế hoạch thu được với cờ theo dõi không có giấy tờ 8795 trên.

Bạn cũng có thể thử một MAX_GRANT_PERCENT gợi ý truy vấn phù hợp hoặc chỉ cần cài đặt (hoặc cung cấp cho SQL Server) đủ bộ nhớ để xử lý khối lượng công việc của bạn.


6

Cả hai kế hoạch có Optimized="false"cho các tham gia bên trong và có hình dạng giống nhau. Tôi hiểu từ bài đăng trên blog được tham chiếu là vấn đề cấp bộ nhớ, trong đó ước tính bảng bên ngoài được sử dụng cho cấp, chỉ áp dụng với Optimized="true". Ngoài ra, cả hai gói này đều có số hàng là 1 cho bảng bên ngoài vòng lặp lồng nhau (bộ đệm bảng với id khóa học đã xóa).

Tôi nghi ngờ thông số cổ điển đánh hơi. Số lượng hàng ước tính của toán tử vòng lặp lồng nhau trước khi xóa chỉ mục cụm cụm CoursePrere conditionAssocation (xóa theo tầng?) Là khoảng 25 triệu trong kế hoạch hàng đầu so với 240 ở kế hoạch dưới cùng. Đó có lẽ là những gì điều khiển bộ nhớ mong muốn.

OPTION(RECOMPILE)có thể là giải pháp dễ nhất và tốt nhất Một cách riêng biệt, điều chỉnh chỉ mục có thể giúp tránh việc quét toàn bộ CoursePrerequisiteAssignmentbảng mỗi khi khóa học bị xóa.


Tôi đang gặp vấn đề tương tự nếu tôi chạy nó mà không có tham số ex: id = 1234, cũng có các chỉ mục trên
CoursePrere conditionAssocation

Số lượng hàng ước tính của vòng lặp lồng nhau với nghĩa đen là gì? Chỉ mục nào trên CoursePrere conditionAssocation có CourseID là cột đầu tiên?
Dan Guzman

Nó trả về 16000 hàng, vâng, có chỉ mục với cột đầu tiên của khóa họcID. tôi chỉ bối rối tại sao số hàng được ước tính cho một là 25 triệu hàng, đây là toàn bộ bảng. Đây có phải là một vấn đề thống kê?
sebeid

Số lượng hàng ước tính với một tham số hoặc bằng chữ được dựa trên biểu đồ thống kê, do đó, nếu số liệu thống kê đó cũ, ước tính số hàng có thể sai và ảnh hưởng đến lựa chọn kế hoạch. Bạn có thể thêm DDL cho các bảng, ràng buộc và chỉ mục cho câu hỏi của bạn không? Tôi ngạc nhiên khi kế hoạch đầu tiên (với ước tính thấp) đang thực hiện quét CoursePrere conditionAssocation thay vì tìm cách sử dụng CourseID.
Dan Guzman
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.