sql-server - 避免针对具有不同注释的相同查询的计划缓存膨胀
问题描述
启用强制参数化的 SQL Server 2017。
我们的应用服务器通过一次登录连接到数据库,因此在 SQL Profiler 中我们看不到真实用户(GUI 用户)的名称。为了查看有关 SQL 服务器级别的信息,我在 NHibernate 中定义了一个拦截器,它在每个查询的开头放置带有用户名的注释。
这解决了问题,但又产生了另一个问题:SQL Server 认为来自不同用户的相同查询是不同的,即使它已正确参数化,唯一的区别是注释。将每个计划乘以 150 会使计划缓存膨胀。
问题:我怎样才能让 SQL Server 认为这些注释查询在计划缓存的哈希方面是相同的?
由于某些遗留应用程序需要它,强制参数化选项已经处于活动状态。
将评论放在查询末尾也不起作用。在我开始尝试其他解决方案(例如创建批处理并将用户信息和实际查询放在 2 个不同的语句中)之前,也许您有一些建议如何格式化注释以避免问题。如果分析器已连接但未在活动监视器或类似工具的“活动昂贵查询”中显示用户名,则批处理黑客将起作用。
以其他方式解决原始问题的 NHibernate 特定技巧也会很棒。
提前感谢您的任何提示!
编辑 2020-06-15:我看到的唯一方法是将批处理与 2 个语句一起使用。第一个将在将 sessionid 映射到当前用户名的小表中进行更新插入。
解决方案
从文档中:
如果 Transact-SQL 语句在字面上匹配先前执行的 Transact-SQL 语句和缓存计划(每个字符一个字符),则该语句符合现有条件。
评论是查询的一部分。没有办法让查询仅因注释而不同以使用相同的查询计划。
您可以通过其他方式传输您的附加信息来实现您的目标,例如将您的用户名放在连接Application Name
属性中,例如此处。
应用程序名称可以在打开连接之前以编程方式设置,但这也会减少连接池中的连接重用。此应用程序名称属性在 SQL 事件探查器中可见。我已经用它来区分应用程序,这确实是它的预期用途。
据我所知,应用程序名称属性不是查询计划缓存键的一部分,因此具有不同的应用程序名称不应导致查询计划缓存未命中。但我还没有真正检查过这个。
推荐阅读
- python - Upgrade to spark2.4.2 from 2.3.1 but mongodb connector stop work
- android - CountryCodePicker 对 EditText 的全号支持
- security - 如何让 Golang 种子初始化更强大
- matlab - 保存未针对优化 matlab fmincon 优化的 x 函数
- excel - 如何在excel中的多行中转置列
- matlab - 在MATLAB中将矩阵及其对应的向量划分为子矩阵和子向量
- javascript - 如何在 jest/enzyme 测试中测试 axios 获取请求功能?
- c++ - 使用 Scatter 和 Gather 的 MPI 矩阵乘法
- xamarin.forms - 鼠标悬停在背景颜色上的图像按钮
- python - 为什么我的模型总是精确地得到 0.5 AUC?