加入收藏 | 设为首页 | 会员中心 | 我要投稿 济南站长网 (https://www.0531zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

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

发布时间:2021-03-14 11:12:23 所属栏目:MsSql教程 来源:网络整理
导读:副标题#e# 运行包含实际执行计划的查询时,根运算符(SELECT)告诉我缓存计划大小为32KB. 连接sys.dm_exec_cached_plans和sys.dm_os_memory_objects的查询,查看有问题的计划,表示pages_in_bytes和max_pages_in_bytes的值为32768(32KB),与缓存的计划大小相匹配.
副标题[/!--empirenews.page--]

运行包含实际执行计划的查询时,根运算符(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计划的节点.

资源:

(编辑:济南站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读