【问题标题】:Parameterized Query creating Many Plans参数化查询创建许多计划
【发布时间】:2018-08-29 12:31:51
【问题描述】:

我有一些参数化的查询,它们每次都在创建新的执行计划,我使用的是 SQL Server 2016

查询类似于:

(@P1 varchar(1043),@P2 varchar(6))
UPDATE table 
SET FILEDATA=@P1 
WHERE FILEID=@P2

这个查询没有使用缓存中已经生成的执行计划,而是每次执行时都创建一个新的计划

This image shows the plancount an individual query is creating

【问题讨论】:

  • (1) 您如何确认他们没有使用相同的计划? (2) 该表中的数据多久更改一次?如果更改过于频繁,统计信息可能会失效,这将迫使引擎重新生成执行计划。 (3) 您是否有任何重复性的工作来重置统计信息或重建该表上的索引? (4) 是否确认计划缓存未满?
  • 1) 我已经运行了一个脚本来获取计划的数量 2) 非常频繁(我可以知道如何验证统计数据)3) 没有这样的工作 4) 是的,我已经验证它不完整
  • (1) 但是您是否真的验证过该查询有重复的计划? (2) 如果数据变化非常频繁——SQL 服务器必须根据新的统计数据更新执行计划——这是一件好事。检查表上的统计信息的最后创建时间,并将其与执行计划上的日期进行比较以进行验证。
  • 按照建议,您首先需要确定您是否有针对同一查询的多个计划(以及多少 个)。请注意,数据类型很重要,连接设置(如 ARTIHABORT)也很重要——这样的事情会使 SQL Server 看到不同的查询。

标签: sql sql-server sql-server-2016 sqlperformance parameterized-query


【解决方案1】:

我过去也遇到过这种情况,以下为我解决了这个问题:

  • 确保所有这些代码都在存储过程中。即使使用参数,存储过程也更有可能重用相同的计划。
  • 我不会重复 Nisarg Shah 在 cmets 中所说的话,因为您似乎已经解决了这些问题,但这些都是非常有效的要检查的事情。
  • 这可能听起来很奇怪,但尽可能完全限定代码。以我的经验,如果它有问题,如果它是这样设计的,更有可能找到现有的计划:

    (@P1 varchar(1043),@P2 varchar(6))
    UPDATE database.dbo.table 
    SET database.dbo.table.FILEDATA=@P1 
    WHERE database.dbo.FILEID=@P2
    

通常我不会这样写我的查询,因为它们似乎有点难以阅读,但过去当我有成堆的计划时,它对我很有用。

【讨论】:

  • 请参阅我在我的问题中添加了一张图片,这可能有助于深入回答这个问题,因为完全合格的查询对我没有帮助提前谢谢
  • 啊,看起来您的@P1 的大小变化足以触发制定新计划。也许这是最好的?如果您想强制它使用相同的计划,这是一个好主意:dba.stackexchange.com/questions/130413/… 如果这不起作用,dba.stackexchange.com 如果您在那里发帖,可能会为您提供更好的答案。祝你好运!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-15
  • 2023-04-03
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 2016-06-08
  • 1970-01-01
相关资源
最近更新 更多