sql-server – 规划缓存大小和保留内存

前端之家收集整理的这篇文章主要介绍了sql-server – 规划缓存大小和保留内存前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
运行包含实际执行计划的查询时,根运算符(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,其中说:

Number of bytes consumed by the cache object.

我无法掌握最后一点拼图,了解它的真正含义.

我知道所有运算符(不是讨论用于排序和散列的额外内存授权)需要一定数量的固定内存,存储状态,进行计算等,这与优化计划一起存储在缓存中,但在哪里?

所以,我的问题是:

> size_in_bytes的真正含义是什么
>为什么它的值高于“缓存计划大小”?
>保留所有运算符/迭代器的固定内存量在哪里,是否具有“缓存计划大小”(在我的示例中为32Kb)或其他任何位置?

我知道他们是具有不同功能的不同DMV,但它们是相关的. sys.dm_exec_cached_plans中的已编译(缓存)计划加入memory_object_address列上的sys.dm_os_memory_objects.我在这里发布问题的原因是,我正在寻求帮助,理解如何解释DMV及其列.

如果size_in_bytes是缓存的计划大小,为什么sql Server在实际执行计划中说另一个值?

查询,新号码:

>实际计划

>缓存计划大小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.

另请注意,此查询不需要对排序和散列操作进行任何额外的内存授予.

Microsoft sql Server 2012 - 11.0.5343.0 (X64)

解决方法

sys.dm_exec_cached_plans DMV的size_in_bytes字段(至少在“编译计划”中)大于XML计划中QueryPlan节点的CachedPlanSize属性的原因是因为编译计划与查询不同计划.编译计划由多个内存对象组成,其组合大小等于size_in_bytes字段.因此,您在文档中找到的“缓存对象消耗的字节数”的描述是准确的;只是在给定DMV名称的情况下很容易误解“缓存对象”的含义,而“计划”这个术语有多重含义.

编译计划是容纳与查询批次相关的各种信息(即,不仅仅是单个语句)的容器,其中一个(或多个)是查询计划.编译计划有一个MEMOBJ_COMPILE_ADHOC的顶级内存对象,它是sys.dm_os_memory_objects中通过两个DMV中的memory_object_address字段链接的行.此内存对象包含符号表,参数集合,相关对象的链接,访问者缓存,TDS元数据缓存以及可能的其他一些项目.编译计划在使用相同会话设置执行相同批处理的会话/用户之间共享.但是,会话/用户之间不共享某些相关对象.

编译计划还有一个或多个依赖对象,可以通过将plan_handle(在sys.dm_exec_cached_plans中)传递到sys.dm_exec_cached_plan_dependent_objects DMF中来找到.有两种类型的依赖对象:可执行计划(Memory Object = MEMOBJ_EXECUTE)和Cursor(Memory Object = MEMOBJ_CURSOREXEC).将有0个或更多Cursor对象,每个光标一个.还将有一个或多个可执行计划对象,每个用户执行同一批处理一个对象,因此用户之间不共享可执行计划.可执行计划包含运行时参数和本地变量信息,运行时状态(如当前正在执行的语句),运行时创建的对象的对象ID(我假设这是指表变量,临时表,临时存储过程等),可能还有其他项目.

多语句批处理中的每个语句都包含在编译语句(Memory Object = MEMOBJ_STATEMENT)中.每个编译语句(即pages_in_bytes)的大小除以1024应该与< QueryPlan>的CachedPlanSize =“xx”值匹配. XML计划中的节点.编译语句通常会有一个(可能更多?)关联的运行时查询计划(Memory Object = MEMOBJ_XSTMT).最后,对于作为查询的每个运行时查询计划,应该存在关联的查询执行上下文(Memory Object = MEMOBJ_QUERYEXECCNTXTFORSE).

对于编译语句,单语句批处理没有单独的编译语句(即MEMOBJ_STATEMENT)或单独的运行时查询计划(即MEMOBJ_XSTMT)对象.每个对象的值将存储在主编译计划对象(即MEMOBJ_COMPILE_ADHOC)中,在这种情况下,该主对象的pages_in_bytes值除以1024应与< QueryPlan>中的CachedPlanSize大小匹配. XML计划的节点.但是,这些值不会等同于多语句批次.

size_in_bytes值可以通过汇总sys.dm_os_memory_objects DMV中的条目(上面以粗体表示的项目)来导出,所有条目都与该编译计划的dm_os_memory_objects.page_allocator_address相关.获取正确值的技巧是首先从sys.dm_exec_cached_plans获取特定编译计划的memory_object_address,然后根据其memory_object_address字段使用该行从sys.dm_os_memory_objects获取相应的MEMOBJ_COMPILE_ADHOC行.然后,从sys.dm_os_memory_objects中获取该行的page_allocator_address值,并使用它从sys.dm_os_memory_objects中获取具有相同page_allocator_address值的所有行. (请注意,此技术不适用于其他缓存对象类型:Parse Tree,Extended Proc,CLR Compiled Proc和CLR Compiled Func.)

使用从sys.dm_exec_cached_plans获取的memory_object_address值,您可以通过以下查询查看编译计划的所有组件:

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;

下面的查询列出了sys.dm_exec_cached_plans中的所有编译计划以及每个批处理的查询计划和语句.上面的查询通过XML作为MemoryObjects字段合并到下面的查询中:

请注意:

> TotalPlanBytes字段只是sys.dm_exec_cached_plans.size_in_bytes字段的重新声明,
> AllocatedBytes字段是相关内存对象的SUM,通常与TotalPlanBytes匹配(即size_in_bytes)
>由于执行期间内存消耗增加,AllocatedBytes字段偶尔会大于TotalPlanBytes(即size_in_bytes).这似乎主要是由于重新编译(这应该是显示1的usecounts字段显而易见)
> BaseSingleStatementPlanKB字段应与XML中QueryPlan节点的CachedPlanSize属性匹配,但仅限于使用单个查询批处理时.
>对于具有多个查询的批处理,sys.dm_os_memory_objects中应该有标记为MEMOBJ_STATEMENT的行,每个查询对应一行.这些行的pages_in_bytes字段应与单个< QueryPlan>匹配. XML计划的节点.

资源:

> What are the different cached objects in the plan cache?
> 1.0 Structure of the Plan Cache and Types of Cached Objects
> 2.0 Sql_Handle and Plan_Handle Explained
> sys.dm_exec_cached_plans的MSDN页面

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],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.[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 = 0x
DECLARE @CompiledPlanAddress VARBINARY(8) = 0x00000001DC4A4060;

SELECT obj.memory_object_address,obj.pages_in_bytes;
DECLARE @CompiledPlanAddress VARBINARY(8) = 0x00000001DC4A4060; SELECT obj.memory_object_address,obj.pages_in_bytes;D0031CD572910529CE001000000xxxxxxxx
ORDER BY cplan.objtype,cplan.plan_handle;

猜你在找的MsSQL相关文章