避免为具有不同评论的相同查询计划缓存膨胀
Avoid plan cache bloat for same query with different comments
SQL 启用强制参数化的 Server 2017。
我们的应用程序服务器通过一次登录连接到数据库,因此在 SQL Profiler 中我们看不到真实用户(GUI 用户)的名称。为了在 SQL 服务器级别上查看该信息,我在 NHibernate 中定义了一个拦截器,它在每个查询的开头放置一个带有用户名的注释。
这解决了问题,但又产生了另一个问题:SQL 服务器认为来自不同用户的相同查询是不同的,即使它已正确参数化并且 唯一不同的是评论。将每个计划乘以 150 会使计划缓存膨胀。
问题:如何让SQL服务器认为那些评论的查询在计划缓存的哈希方面是相同的?
强制参数化选项已处于活动状态,因为某些旧版应用需要它。
将评论放在查询的末尾也不起作用。
在我开始尝试其他解决方案之前,例如创建批处理并将用户信息和实际查询放在 2 个不同的语句中,也许您对如何格式化评论以避免出现问题有一些建议。如果探查器已连接但未在 activity 监视器或类似工具的 "active expensive queries" 中显示用户名,则批处理 hack 将起作用。
以其他方式解决原始问题的 NHibernate 特定技巧也很棒。
提前感谢您的任何提示!
编辑 2020-06-15:我看到的唯一方法是使用带有 2 个语句的批处理。第一个将插入一个小的 table ,将 sessionid 映射到当前用户名。
The Transact-SQL statement qualifies as existing if it literally matches a previously executed Transact-SQL statement with a cached plan, character per character.
评论是查询的一部分。无法使查询仅因注释不同而使用相同的查询计划。
您可以通过其他方式传输您的附加信息来实现您的目标,例如将您的用户名放在连接 Application Name
属性 中,例如 here.
可以在打开连接之前以编程方式设置应用程序名称,但这也会减少池中的连接重用。此应用程序名称 属性 在 SQL 探查器中可见。我已经用它来区分应用程序了,这确实是它的预期用途。
据我所知,应用程序名称 属性 不是查询计划缓存键的一部分,因此具有不同的应用程序名称不应导致查询计划缓存未命中。但是我没有实际检查过这个。
SQL 启用强制参数化的 Server 2017。
我们的应用程序服务器通过一次登录连接到数据库,因此在 SQL Profiler 中我们看不到真实用户(GUI 用户)的名称。为了在 SQL 服务器级别上查看该信息,我在 NHibernate 中定义了一个拦截器,它在每个查询的开头放置一个带有用户名的注释。
这解决了问题,但又产生了另一个问题:SQL 服务器认为来自不同用户的相同查询是不同的,即使它已正确参数化并且 唯一不同的是评论。将每个计划乘以 150 会使计划缓存膨胀。
问题:如何让SQL服务器认为那些评论的查询在计划缓存的哈希方面是相同的?
强制参数化选项已处于活动状态,因为某些旧版应用需要它。
将评论放在查询的末尾也不起作用。 在我开始尝试其他解决方案之前,例如创建批处理并将用户信息和实际查询放在 2 个不同的语句中,也许您对如何格式化评论以避免出现问题有一些建议。如果探查器已连接但未在 activity 监视器或类似工具的 "active expensive queries" 中显示用户名,则批处理 hack 将起作用。
以其他方式解决原始问题的 NHibernate 特定技巧也很棒。
提前感谢您的任何提示!
编辑 2020-06-15:我看到的唯一方法是使用带有 2 个语句的批处理。第一个将插入一个小的 table ,将 sessionid 映射到当前用户名。
The Transact-SQL statement qualifies as existing if it literally matches a previously executed Transact-SQL statement with a cached plan, character per character.
评论是查询的一部分。无法使查询仅因注释不同而使用相同的查询计划。
您可以通过其他方式传输您的附加信息来实现您的目标,例如将您的用户名放在连接 Application Name
属性 中,例如 here.
可以在打开连接之前以编程方式设置应用程序名称,但这也会减少池中的连接重用。此应用程序名称 属性 在 SQL 探查器中可见。我已经用它来区分应用程序了,这确实是它的预期用途。
据我所知,应用程序名称 属性 不是查询计划缓存键的一部分,因此具有不同的应用程序名称不应导致查询计划缓存未命中。但是我没有实际检查过这个。