Questions tagged «plan-cache»

1
计划缓存大小和保留内存
当运行包括实际执行计划在内的查询时,根运算符(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_bytes49152(48KB)中的值代表什么。我已经在所有这些专栏中阅读了BOL,尤其是size_in_bytes这样说: “ 缓存对象消耗的字节数。 ” 我无法理解难题的最后一部分,以了解其真正含义。 我知道所有运算符(不是在谈论用于排序和散列的额外内存授予)都需要一定数量的固定内存来存储状态,进行计算等,这些内存与优化后的计划一起存储在缓存中,但是在哪里? 因此,我的问题是: 到底是size_in_bytes什么意思 为什么它的值比“缓存的计划大小”高? 为所有操作员/迭代器保留的固定内存量是哪里,是使用“缓存的计划大小”(在我的示例中为32Kb)还是其他任何地方? 我知道它们是具有不同功能的不同DMV,但它们是相关的。在编译(缓存)计划sys.dm_exec_cached_plans加入sys.dm_os_memory_objects在memory_object_address列。我在此处发布问题的原因是,我正在寻求帮助,了解如何解释DMV及其列。 如果size_in_bytes是缓存的计划大小,为什么SQL Server在实际执行计划中说另一个值? 新查询,新数字: 实际计划 缓存的计划大小16KB 编译内存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)

2
使用SqlCommand.Prepare()有什么意义和好处?
我遇到了开发人员代码,其中在执行SQL查询之前广泛使用了SqlCommand.Prepare()(请参见MSDN)方法。我想知道这样做的好处是什么? 样品: command.Prepare(); command.ExecuteNonQuery(); //... command.Parameters[0].Value = 20; command.ExecuteNonQuery(); 我玩了一些,并进行了追踪。调用Prepare()方法后,Command的执行使Sql Server执行以下语句: declare @p1 int set @p1=1 exec sp_prepexec @p1 output,N'@id int,@desc text',N'INSERT INTO dbo.testtable (id) VALUES (@id)',@id=20' select @p1 之后,当获取参数的值并SqlCommand.ExecuteNonQuery()调用该参数时,将在Sql-Server上执行以下操作: exec sp_execute 1,@id=20 对我来说,这看起来像该语句在Prepare()执行后立即得到了编译。我想知道这样做有什么好处?这是否意味着将其放入计划缓存中,并且可以在使用所需参数值执行最终查询后立即重新使用它? 我发现(并记录在另一个问题中)用SqlParameters执行的SqlCommands总是包装在sp_executesql过程调用中。这使Sql Server能够独立于参数值存储和重用计划。 关于这一点,我想知道该prepare()方法是无用的还是过时的,或者我是否在这里遗漏了什么?

2
缺少存储过程的执行计划
存储过程的缓存中缺少计划的原因是什么? WITH RECOMPILE 动态SQL 加密代码 重大数据更改 更新统计 还有什么? 我最近在2台服务器(SQL Server 2008 R2和SQL Server 2012)上工作,这些服务器在缓存中没有计划用于非常占用资源的存储过程。存储过程中的许多(也许是全部)语句在缓存中也没有计划。一些存储过程非常频繁地执行,例如每秒执行几次。 没有任何记忆压力。其中一台服务器的硬件远远超出了所需。 我认为丢失的计划是由于在存储过程中间创建了临时表,但这似乎是来自SQL Server 2000或更早版本的旧信息。从SQL Server 2005开始,重新编译在DDL之后的语句的语句级别进行。在所有情况下都是如此吗,还是在新版本中仍然会发生? 遗失计划的罪魁祸首是什么?我已经浏览了有关该主题的几篇文章,但似乎没有什么合适的选择。 我本周要查看的服务器上启用了针对临时工作负载的优化。其中一个存储过程每天仅执行一次。我确实有那个的代码。我没有每分钟执行100次以上的代码,但我可以理解。我将无法发布代码,但是我可以根据自己的问题进行描述。 我不相信任何人都可以释放过程高速缓存或删除干净的缓冲区。该客户正在使用Solarwinds DPA作为其监视工具之一。DPA确实在每天被调用的存储过程中捕获了该语句的执行计划之一。由于不可保留的WHERE子句,该语句具有大量读取。如果DPA捕获了该语句,则它是一个估计的计划,并且一次在计划缓存中。当我们进行故障排除时,只是不存在。我将让他们开始记录sp_WhoIsActive到表中。 我正在使用sp_BlitzCache。(我为Brent Ozar Unlimited工作)将显示整个存储过程的计划以及单个语句(如果存在)的计划。如果它们不存在,则会发出警告“我们找不到该查询的计划。可能的原因包括动态SQL,RECOMPILE提示和加密代码。” 声明上也有警告。 TF 2371未安装。我正在查看等待统计信息。服务器很无聊。PLE超过130,000。 我现在有另外2个存储过程的代码。其中之一是使用动态SQL,exec (@sql)这样我们就知道为什么没有针对它的计划。但是另一种(每分钟运行100次以上)没有任何异常。唯一突出的一点是,临时表是在超过1000行代码的中间创建的。它也确实调用了一堆子存储过程。 关于SQL Server 2008中的计划缓存,我没有看到任何> = 8k的文字,但是其中一个存储过程在调用另一个存储过程之前就对批量插入发表了评论。但是批量插入没有出现在我正在查看的外部存储过程中。本文的“重新编译阈值”部分很有趣。我看到的临时表是大量的INSERT(可能导致数百万行),一些更新和删除。因此,大量数据更改到临时表。百万。

1
将查询计划按语句拆分以提高可重用性会更好吗?
从我对查询计划如何通过查询进行编译,存储和检索的有限知识中,我了解到多语句查询或存储过程将生成其查询计划,该查询计划将存储在查询计划缓存中,以供查询在将来的执行中使用。 我认为此计划是使用查询哈希从查询计划缓存中检索的,这意味着如果编辑并执行查询,哈希将有所不同,并且会生成新计划,因为在查询计划缓存中找不到匹配的哈希。 我的问题是:如果用户执行多语句查询中的语句之一的语句,是否可以将缓存中已存在的查询计划的相关部分用于多语句查询?我希望答案是否定的,因为哈希值显然不匹配,但是对多语句查询中的每个语句进行哈希处理会更好些,以便用户在查询中运行单个语句可以使用它们吗? 我希望有一些我没有考虑到的复杂因素(而这正是我真正想知道的),但似乎我们可以在许多查询计划中存储相同的“语句计划”,从而占用更多空间并占用更多时间CPU和生成时间。 可能只是显示我的无知。

1
检测到SQLHANDLE的可能的无限重新编译
我一直在sql错误日志中发现奇怪的错误消息: Bocss:每小时都会发生同样的僵局–需要调查 此外,按照以下示例,错误日志中还列出了许多其他SPID的重新编译内容: 2015年9月4日14:30:10,spid64,未知,为SQLHANDLE检测到可能的无限重新编译0x0200000059631A288882589E0C54B76404CAE1B97E08D368000000000000000000000000000000000000000000 PlanHandle 0x0600040059631A2860A62B654100000001000000000000000000000000000000000000600最后一次补偿是10:30/04/04:10:04/04 /结尾,spid150,未知,已检测到SQLHANDLE 0x02000000EF886F018C4E0B163812B8B20150FE8FC7E6A06A000000000000000000000000000000000000000000 PlanHandle 0x06000400EF886F01901A816E0600000001000000000000000000000000000000000000000000000000000000的可能无限重新编译,起始偏移量998Uncompute 09,20 09:09结束,偏移量2020是:0909结束时的偏移量2020:20,09:09结束,偏移量2030:0检测到可能无限的重新编译为SQLHANDLE 0x0200000057C4C632D9052275CFF2B683B80F29501EE91D730000000000000000000000000000000000000000 PlanHandle 0x0600040057C4C63200EAC2BE3000000001000000000000000000000000000000000000000000000000000000起始偏移1064结束偏移2652是2. 2015年9月4日14最后重新编译原因:30:09,spid163,未知,是为SQLHANDLE 0x02000000E7C7BF0E5D70DE55759C7842860272AD474D69AB0000000000000000000000000000000000000000 PlanHandle探测到一个可能无限的重新编译0x06000400E7C7BF0EF0EB68A52C00000001000000000000000000000000000000000000000000000000000000000000起始偏移量1028终止偏移量2580.上次重新编译的原因是2。 是什么原因造成的? 看来我已经没有计划在缓存中了。 按照这篇文章的建议 http://www.sqlservercentral.com/Forums/Topic1479420-146-1.aspx 然后作为一项安全措施禁用了全文目录,这没有什么区别,因此我完全回滚了更改(删除了新对象等)。这也没有什么不同,最终似乎唯一阻止它的是重启SQL实例,这立即解决了问题。 这样也可以解决我的问题,但是,我仍然首先要找出是什么原因造成了这种混乱?

1
测量计划驱逐
我们有一个SQL Server 2016 SP1,最大内存设置为24GB。 该服务器具有大量编译,其中只有10%的编译来自临时查询。因此,新编译的计划应存储在计划缓存中,但计划缓存的大小不会增加(约3.72GB)。 我怀疑本地内存压力会导致从缓存中删除计划。计划缓存压力限制为5GB。(0-4GB的可见目标内存的75%+ 4GB-64GB的可见目标内存的10%+> 64GB的可见目标内存的5%)。当缓存存储达到压力限制的75%时,应从缓存中删除计划。就我而言,5 GB的75%为3.75 GB。因此,这可能是高编译率的原因。 有没有一种方法可以测量(性能,扩展事件等)从缓存中删除计划?这样我就可以确定本地内存压力确实是高编译的原因吗?


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.