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 lô 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ải làchia 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 Proc và CLR 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: