sql-server – 规划缓存大小和保留内存
副标题[/!--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,其中说:
我无法掌握最后一点拼图,了解它的真正含义. 我知道所有运算符(不是讨论用于排序和散列的额外内存授权)需要一定数量的固定内存,存储状态,进行计算等,这与优化计划一起存储在缓存中,但在哪里? 所以,我的问题是: > size_in_bytes的真正含义是什么 我知道他们是具有不同功能的不同DMV,但它们是相关的. sys.dm_exec_cached_plans中的已编译(缓存)计划加入memory_object_address列上的sys.dm_os_memory_objects.我在这里发布问题的原因是,我正在寻求帮助,理解如何解释DMV及其列. 如果size_in_bytes是缓存的计划大小,为什么SQL Server在实际执行计划中说另一个值? 新查询,新号码: >实际计划 >缓存计划大小16KB > DMV: > sys.dm_exec_cached_plans.size_in_bytes 24KB 另请注意,此查询不需要对排序和散列操作进行任何额外的内存授予. 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字段合并到下面的查询中:
|