Gor*_*ddy 19 sql-server memory dmv sql-server-2012 plan-cache
运行包含实际执行计划的查询时,根运算符 ( SELECT) 告诉我缓存计划大小为 32KB。
该连接的查询sys.dm_exec_cached_plans和sys.dm_os_memory_objects,看问题的计划,称该值pages_in_bytes和max_pages_in_bytes为32768(32KB),它匹配缓存计划的大小。
我不明白的是 中的值sys.dm_exec_cached_plans.size_in_bytes,即 49152 (48KB) 代表什么。我已经阅读了所有这些专栏的 BOL,特别是size_in_bytes其中说:
"缓存对象消耗的字节数。 "
我无法解决最后一点难题,无法理解它的真正含义。
我知道所有操作符(不是谈论用于排序和散列的额外内存授予)都需要一定数量的固定内存,以存储状态、进行计算等,这些内存与缓存中的优化计划一起存储,但在哪里?
所以,我的问题是:
size_in_bytes意思我知道它们是具有不同功能的不同 DMV,但它们是相关的。在编译(缓存)计划sys.dm_exec_cached_plans加入sys.dm_os_memory_objects在memory_object_address列。我在这里发布问题的原因是我在寻求帮助,了解如何解释 DMV 及其专栏。
如果size_in_bytes是缓存计划大小,为什么SQL Server在实际执行计划中说另一个值?
新查询,新号码:
sys.dm_exec_cached_plans.size_in_bytes 24KBsys.dm_os_memory_objects.pages_in_bytes, .max_pages_in_bytes 16KB。另请注意,此查询不需要为排序和散列操作分配任何额外的内存。
Microsoft SQL Server 2012 - 11.0.5343.0 (X64)
Sol*_*zky 13
DMV的size_in_bytes字段sys.dm_exec_cached_plans,至少在“编译计划”方面,比XML计划中节点的CachedPlanSize属性大的QueryPlan原因是因为编译计划与查询计划不是一回事。编译计划由多个内存对象组成,其组合大小等于该size_in_bytes字段。因此,您在文档中找到的“缓存对象消耗的字节数”的描述是准确的;只是鉴于 DMV 的名称很容易误解“缓存对象”的含义,并且术语“计划”具有多种含义。
编译计划是一个容器,其中包含与查询批处理相关的各种信息(即不仅仅是单个语句),其中一个(或多个)信息是查询计划。编译计划具有MEMOBJ_COMPILE_ADHOC的顶级内存对象,它是sys.dm_os_memory_objects通过memory_object_address两个 DMV 中的字段链接的行。该内存对象包含符号表、参数集合、相关对象的链接、访问器缓存、TDS 元数据缓存以及可能的其他一些项目。编译计划在使用相同会话设置执行同一批次的会话/用户之间共享。但是,某些相关对象在会话/用户之间不共享。
编译计划还具有一个或多个相关对象,可以通过将plan_handle(in sys.dm_exec_cached_plans)传递到sys.dm_exec_cached_plan_dependent_objectsDMF来找到这些对象。有两种类型的依赖对象:可执行计划(内存对象 = MEMOBJ_EXECUTE)和游标(内存对象 = MEMOBJ_CURSOREXEC)。将有 0 个或多个 Cursor 对象,每个游标一个。还将有一个或多个可执行计划对象,每个执行同一批次的每个用户一个,因此可执行计划是不是用户之间共享。可执行计划包含运行时参数和局部变量信息、运行时状态(例如当前执行的语句)、运行时创建的对象的对象 ID(我假设这是指表变量、临时表、临时存储过程等) ,可能还有其他项目。
多语句批处理中的每个语句都包含在编译语句(内存对象 = MEMOBJ_STATEMENT)中。每个 Compiled Statement (即pages_in_bytes) 除以 1024 的大小应该与XML 计划中节点的CachedPlanSize="xx"值匹配<QueryPlan>。编译语句通常会有一个(可能更多?)关联的运行时查询计划(内存对象 = MEMOBJ_XSTMT)。最后,对于作为查询的每个运行时查询计划,都应该有一个关联的查询执行上下文(内存对象 = MEMOBJ_QUERYEXECCNTTXTFORSE)。
关于编译语句,单语句批处理没有单独的编译语句(即MEMOBJ_STATEMENT)或单独的运行时查询计划(即MEMOBJ_XSTMT)对象。每个对象的值将存储在主编译计划对象(即MEMOBJ_COMPILE_ADHOC)中,在这种情况下,该pages_in_bytes主对象的值除以 1024 应与XML 计划节点中的CachedPlanSize大小匹配<QueryPlan>。但是,在多语句批次中,这些值不相等。
该size_in_bytes值可以通过对sys.dm_os_memory_objectsDMV 中的条目(上面以粗体表示的项目)求和得出,所有这些条目都与dm_os_memory_objects.page_allocator_address该编译计划相关。获取正确值的技巧是首先获取特定编译计划的memory_object_addressfrom sys.dm_exec_cached_plans,然后使用它根据其字段获取相应的MEMOBJ_COMPILE_ADHOC行。然后,从该行中获取值,并使用它来获取具有相同值的所有行。(请注意,此技术不适用于其他缓存对象类型:解析树、扩展过程、CLR 编译过程和。)sys.dm_os_memory_objectsmemory_object_addresspage_allocator_addresssys.dm_os_memory_objectssys.dm_os_memory_objectspage_allocator_addressCLR Compiled Func
使用从memory_object_address获得的值sys.dm_exec_cached_plans,您可以通过以下查询查看编译计划的所有组件:
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;
Run Code Online (Sandbox Code Playgroud)
下面的查询列出了所有编译计划sys.dm_exec_cached_plans以及每个批次的查询计划和语句。上面的查询通过 XML 作为MemoryObjects字段合并到下面的查询中:
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;
Run Code Online (Sandbox Code Playgroud)
请注意:
TotalPlanBytes字段只是该字段的重新声明sys.dm_exec_cached_plans.size_in_bytes,AllocatedBytes字段是通常匹配的相关内存对象的总和TotalPlanBytes(即size_in_bytes)AllocatedBytes字段偶尔会大于TotalPlanBytes(即size_in_bytes)。这似乎主要是由于重新编译(这应该在usecounts字段显示中很明显1)BaseSingleStatementPlanKB字段应与XML 中节点的CachedPlanSize属性匹配QueryPlan,但仅限于使用单个查询批处理时。MEMOBJ_STATEMENTin 的行sys.dm_os_memory_objects,每个查询一个。pages_in_bytes这些行的字段应与<QueryPlan>XML 计划的各个节点匹配。资源: