Lập kế hoạch kích thước bộ nhớ cache và bộ nhớ dành riêng


18

Khi chạy truy vấn bao gồm Kế hoạch thực thi thực tế, toán tử gốc ( SELECT) cho tôi biết Kích thước gói được lưu trong bộ nhớ cache là 32KB.

Một truy vấn tham gia sys.dm_exec_cached_planssys.dm_os_memory_objects, nhìn vào kế hoạch được đề cập, nói rằng các giá trị cho pages_in_bytesmax_pages_in_byteslà 32768 (32KB), phù hợp với kích thước kế hoạch được lưu trong bộ nhớ cache.

Điều tôi không hiểu là giá trị trong sys.dm_exec_cached_plans.size_in_bytes4952 (48KB) là viết tắt của từ gì. Tôi đã đọc BOL trên tất cả các cột này và đặc biệt là size_in_bytes:

" Số byte được tiêu thụ bởi đối tượng bộ đệm. "

Tôi không thể hiểu được câu đố cuối cùng đó để hiểu ý nghĩa thực sự của nó.

Tôi biết rằng tất cả các toán tử (không nói về cấp bộ nhớ bổ sung được sử dụng cho sắp xếp và băm) yêu cầu một số lượng bộ nhớ cố định, để lưu trữ trạng thái, tính toán, v.v., được lưu trữ với gói tối ưu hóa trong bộ đệm, nhưng ở đâu?

Vì vậy, câu hỏi của tôi là:

  • Điều đó size_in_bytesthực sự có nghĩa là gì
  • Tại sao nó có giá trị cao hơn "kích thước gói được lưu trong bộ nhớ cache"?
  • Số lượng bộ nhớ cố định cho tất cả các toán tử / bộ lặp được dành riêng ở đâu, có phải với "kích thước gói được lưu trong bộ nhớ cache" (trong ví dụ của tôi là 32Kb) hay bất cứ nơi nào khác không?

Tôi biết chúng là các DMV khác nhau với các chức năng khác nhau, nhưng chúng có liên quan. Các kế hoạch được biên dịch (lưu trữ) trong các phép sys.dm_exec_cached_plansnối sys.dm_os_memory_objectstrên memory_object_addresscột. Lý do tôi đăng câu hỏi ở đây là vì tôi đang yêu cầu trợ giúp về vấn đề này, hiểu cách diễn giải DMV và các cột của họ.

Nếu size_in_byteskích thước kế hoạch được lưu trong bộ nhớ cache, tại sao SQL Server lại nói một giá trị khác trong kế hoạch thực hiện thực tế?

Truy vấn mới, số mới:

  • Kế hoạch thực tế
    • Kích thước gói bộ nhớ cache 16KB
    • CompileMemory 96KB
  • DMV:
    • sys.dm_exec_cached_plans.size_in_bytes 24KB
    • sys.dm_os_memory_objects.pages_in_bytes, .max_pages_in_bytes 16KB.

Ngoài ra, lưu ý rằng truy vấn này không yêu cầu bất kỳ cấp bộ nhớ bổ sung nào cho các hoạt động sắp xếp và băm.

Máy chủ Microsoft SQL 2012 - 11.0.5343.0 (X64)

Câu trả lời:


12

Lý do mà size_in_bytestrường sys.dm_exec_cached_plansDMV, ít nhất là về "Gói biên dịch", lớn hơn CachedPlanSizethuộc tính của QueryPlannút trong kế hoạch XML là vì Kế hoạch biên dịch không giống với Kế hoạch truy vấn. Gói tổng hợp bao gồm nhiều đối tượng bộ nhớ, kích thước kết hợp tương đương với size_in_bytestrường. Vì vậy, mô tả về " Số byte được tiêu thụ bởi đối tượng bộ đệm " mà bạn tìm thấy trong tài liệu là chính xác; chỉ đơn giản là dễ hiểu sai ý nghĩa của "đối tượng bộ đệm" được đặt tên của DMV và thuật ngữ "kế hoạch" có nhiều nghĩa.

Gói biên dịch là một thùng chứa các phần thông tin khác nhau liên quan đến truy vấn (nghĩa là không chỉ một câu lệnh), một (hoặc nhiều) trong số các phần đó là (các) gói truy vấn. Các gói được biên dịch có Đối tượng bộ nhớ cấp cao nhất là MEMOBJ_COMPILE_ADHOC , là hàng trong sys.dm_os_memory_objectsđó được liên kết thông qua memory_object_addresstrường trong cả hai DMV. Đối tượng bộ nhớ này chứa bảng biểu tượng, bộ sưu tập tham số, liên kết đến các đối tượng liên quan, bộ đệm truy cập, bộ đệm siêu dữ liệu TDS và có thể một số mục khác. Gói tổng hợp được chia sẻ giữa các Phiên / Người dùng đang thực hiện cùng một đợt với cùng cài đặt Phiên. Tuy nhiên, một số đối tượng liên quan không được chia sẻ giữa Phiên / Người dùng.

Các gói đã biên dịch cũng có một hoặc nhiều đối tượng phụ thuộc có thể được tìm thấy bằng cách chuyển plan_handle(trong sys.dm_exec_cached_plans) vào sys.dm_exec_cached_plan_dependent_objectsDMF. Có hai loại đối tượng phụ thuộc: Kế hoạch thực thi (Đối tượng bộ nhớ = MEMOBJ_EXECUTE ) và Con trỏ (Đối tượng bộ nhớ = MEMOBJ_CURSOREXEC ). Sẽ có 0 hoặc nhiều đối tượng Con trỏ, mỗi đối tượng con trỏ. Cũng sẽ có một hoặc nhiều đối tượng Kế hoạch thực thi, mỗi đối tượng mỗi Người dùng thực hiện cùng một đợt , do đó, các Kế hoạch thực thi không phảichia sẻ giữa những người dùng. Các gói thực thi chứa tham số thời gian chạy và thông tin biến cục bộ, trạng thái thời gian chạy như câu lệnh hiện đang thực thi, id đối tượng cho các đối tượng được tạo tại thời gian chạy (Tôi giả sử điều này đề cập đến Biến bảng, Bảng tạm thời, Quy trình lưu trữ tạm thời, v.v.) , và có thể các mặt hàng khác.

Mỗi câu lệnh trong một lô nhiều câu lệnh được chứa trong Câu lệnh được biên dịch (Đối tượng bộ nhớ = MEMOBJ_STATEMENT ). Kích thước của mỗi Câu lệnh được biên dịch (nghĩa là pages_in_bytes) chia cho 1024 phải khớp với các CachedPlanSize="xx"giá trị của các <QueryPlan>nút trong kế hoạch XML. Các câu lệnh được biên dịch thường sẽ có một (có thể nhiều hơn?) Các kế hoạch truy vấn thời gian chạy liên quan (Bộ nhớ đối tượng = MEMOBJ_XSTMT ). Cuối cùng, đối với mỗi Kế hoạch truy vấn thời gian chạy là một truy vấn, cần có một Bối cảnh thực thi truy vấn có liên quan (Đối tượng bộ nhớ = MEMOBJ_QUERYEXECCNTXTFORSE ).

Đối với Báo cáo Biên soạn với, lô duy nhất tuyên bố không có Tuyên bố riêng Biên soạn (tức MEMOBJ_STATEMENT ) hoặc thời gian chạy riêng biệt Kế hoạch truy vấn (ví dụ MEMOBJ_XSTMT ) đối tượng. Giá trị cho từng đối tượng đó sẽ được lưu trữ trong đối tượng Kế hoạch tổng hợp chính (ví dụ MEMOBJ_COMPILE_ADHOC ) và trong trường hợp đó, pages_in_bytesgiá trị cho đối tượng chính đó chia cho 1024 phải khớp với CachedPlanSizekích thước trong <QueryPlan>nút của kế hoạch XML. Tuy nhiên, các giá trị đó sẽ không bằng nhau trong các lô đa câu lệnh.


Các size_in_bytesgiá trị có thể được rút ra bằng cách tổng hợp các mục trong sys.dm_os_memory_objectsDMV (các mục đã nêu ở trên in đậm), tất cả các liên quan bằng cách dm_os_memory_objects.page_allocator_addresscho rằng Biên soạn kế hoạch. Mẹo để có được giá trị chính xác là trước tiên hãy lấy memory_object_addresstừ sys.dm_exec_cached_plansmột Gói tổng hợp cụ thể, sau đó sử dụng giá trị đó để lấy hàng MEMOBJ_COMPILE_ADHOC tương ứng sys.dm_os_memory_objectsdựa trên memory_object_addresstrường của nó . Sau đó, lấy page_allocator_addressgiá trị từ sys.dm_os_memory_objectscho hàng đó và sử dụng nó để lấy tất cả các hàng từ sys.dm_os_memory_objectsđó có cùng page_allocator_addressgiá trị. (Xin lưu ý rằng kỹ thuật này không hoạt động đối với các loại Đối tượng được lưu trong bộ nhớ cache khác: Parse Tree , Extended Proc , CLR Compiled ProcCLR Compiled Func.)

Sử dụng memory_object_addressgiá trị thu được từ sys.dm_exec_cached_plans, bạn có thể thấy tất cả các thành phần của Gói tổng hợp thông qua truy vấn sau:

DECLARE @CompiledPlanAddress VARBINARY(8) = 0x00000001DC4A4060;

SELECT obj.memory_object_address, obj.pages_in_bytes, obj.type
FROM   sys.dm_os_memory_objects obj
WHERE  obj.page_allocator_address = (
                               SELECT planobj.page_allocator_address
                               FROM   sys.dm_os_memory_objects planobj
                               WHERE  planobj.memory_object_address = @CompiledPlanAddress
                              )
ORDER BY obj.[type], obj.pages_in_bytes;

Truy vấn bên dưới liệt kê tất cả các Kế hoạch được biên dịch sys.dm_exec_cached_planscùng với Kế hoạch truy vấn và các câu lệnh cho từng lô. Truy vấn trực tiếp ở trên được kết hợp vào truy vấn bên dưới thông qua XML dưới dạng MemoryObjectstrường:

SELECT cplan.bucketid,
       cplan.pool_id,
       cplan.refcounts,
       cplan.usecounts,
       cplan.size_in_bytes,
       cplan.memory_object_address,
       cplan.cacheobjtype,
       cplan.objtype,
       cplan.plan_handle,
       '---' AS [---],
       qrypln.[query_plan],
       sqltxt.[text],
       '---' AS [---],
       planobj.pages_in_bytes,
       planobj.pages_in_bytes / 1024 AS [BaseSingleStatementPlanKB],
       '===' AS [===],
       cplan.size_in_bytes AS [TotalPlanBytes],
       bytes.AllocatedBytes,
       (SELECT CONVERT(VARCHAR(30), obj.memory_object_address, 1)
               AS [memory_object_address], obj.pages_in_bytes, obj.[type]
               --,obj.page_size_in_bytes
        FROM   sys.dm_os_memory_objects obj
        WHERE  obj.page_allocator_address = planobj.page_allocator_address
        FOR XML RAW(N'object'), ROOT(N'memory_objects'), TYPE) AS [MemoryObjects]
FROM   sys.dm_exec_cached_plans cplan
OUTER APPLY sys.dm_exec_sql_text(cplan.[plan_handle]) sqltxt
OUTER APPLY sys.dm_exec_query_plan(cplan.[plan_handle]) qrypln
INNER JOIN sys.dm_os_memory_objects planobj
        ON planobj.memory_object_address = cplan.memory_object_address
OUTER APPLY (SELECT SUM(domo.[pages_in_bytes]) AS [AllocatedBytes]
             FROM   sys.dm_os_memory_objects domo
             WHERE  domo.page_allocator_address = planobj.page_allocator_address) bytes
WHERE  cplan.parent_plan_handle IS NULL
AND    cplan.cacheobjtype IN (N'Compiled Plan', N'Compiled Plan Stub')
--AND cplan.plan_handle = 0x06000D0031CD572910529CE001000000xxxxxxxx
ORDER BY cplan.objtype, cplan.plan_handle;

Xin lưu ý rằng:

  • các TotalPlanByteslĩnh vực chỉ là một tái tuyên bố của sys.dm_exec_cached_plans.size_in_byteslĩnh vực,
  • các AllocatedByteslĩnh vực là SUM của các đối tượng bộ nhớ liên quan mà thường phù hợp TotalPlanBytes(ví dụ size_in_bytes)
  • các AllocatedByteslĩnh vực sẽ thường xuyên được lớn hơn TotalPlanBytes(ví dụ size_in_bytes) do tiêu thụ bộ nhớ tăng trong thời gian thực. Điều này dường như xảy ra chủ yếu là do biên dịch lại (điều này hiển nhiên với usecountstrường hiển thị 1)
  • các BaseSingleStatementPlanKBlĩnh vực nên phù hợp với CachedPlanSizethuộc tính của QueryPlannút trong XML, nhưng chỉ khi sử dụng một loạt câu hỏi duy nhất.
  • cho lô với nhiều truy vấn, có nên được hàng đánh dấu là MEMOBJ_STATEMENTtrong sys.dm_os_memory_objects, một cho mỗi truy vấn. Các pages_in_byteslĩnh vực cho những hàng phải phù hợp với từng <QueryPlan>nút của kế hoạch XML.

Tài nguyên:

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.