避免参数嗅探带来的资源消耗
来源:互联网 发布:男友活好的体验 知乎 编辑:程序博客网 时间:2024/05/07 13:03
近日发现一个服务器上的TRACE文件中记录了大量同一类型的SQL,而这个SQL看上去貌似没什么问题。
exec sp_executesql N' SELECT UserID, UserCategory, UserName, PartnerID, PartnerName, CreatedTime FROM [table] WITH(NOLOCK) WHERE UserCategory = @UserCategory AND PartnerID = @PartnerID ',N'@UserCategory nvarchar(50),@PartnerID nvarchar(50)',@UserCategory=N'fee3c20d30964637809c7cc68c45243b',@PartnerID=N'5DFAEB3BE6377159FE3548DA39E9936F'
(1 行受影响)
表 ''。扫描计数 1,逻辑读取 18131 次,物理读取 1 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
(1 行受影响)
SQL Server 执行时间:
CPU 时间 = 1451 毫秒,占用时间 = 1478 毫秒。
SQL Server 执行时间:
CPU 时间 = 1466 毫秒,占用时间 = 1890 毫秒。
SQL Server 分析和编译时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
相应的索引在表上也存在,应该执行的比较快才对,并且对CPU和IO 的消耗也不应该如此多。观察了此SQL 的执行计划,发现在执行索引查找的时候,选择的是范围查询,与预想中的等值查询不一致。从执行计划可以看出,SQL SERVER在执行查询的时候,发生了参数嗅探。原因可能是SQL 语句中有强制参数化的行为.(强制参数化只是执行计划发生参数嗅探的一个因素,是否出现参数嗅探还和表中的数据量等其它因素有关。)
既然原因大致明了了,改进的方向大致也有了,SQL SERVER在编译SQL 的时候会进行简单参数化,大可不必因担心执行计划不可以重用而将SQL强制参数化。
将这个查询改成了一个存储过程,目的是使这个SQL的执行计划在编译的时候简单参数化,避免出现查询谓词范围查询。
CREATE PROCEDURE [dbo].[GetPartnerUsers_test]
-- Add the parameters for the stored procedure here
@UserCategory nvarchar(50),
@PartnerID nvarchar(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
declare @sql nvarchar(max)
-- Insert statements for procedure here
set @sql='SELECT UserID, UserCategory, UserName, PartnerID, PartnerName, CreatedTime FROM [table] WITH(NOLOCK)'
+' WHERE UserCategory =''' +@UserCategory+''' AND PartnerID = '''+@PartnerID+''''
--print @sql
exec(@sql)
END
新的执行计划如下:
表 ''。扫描计数 0,逻辑读取 7 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 1 毫秒。
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 1 毫秒。
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 2 毫秒。
SQL Server 分析和编译时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
资源消耗对比可以看出,前者比后者至少多三个数量级。
- 避免参数嗅探带来的资源消耗
- PG资源消耗相关参数
- Java Collection 集合类大小调整带来的性能消耗
- 资源消耗很小的内存池代码
- 如何定位资源消耗多的SQL
- 查看数据库资源的消耗情况
- 消耗CPU资源的shell脚本
- 定位高消耗资源的sql语句
- 查找消耗资源多的sql
- 揪出偷偷消耗资源的黑手!
- Unity 关于资源加载的时间消耗
- 避免代理服务器的缓存带来的问题
- 避免代理服务器的缓存带来的问题
- 如何避免重构带来的危险
- 如何避免重构带来的危险
- 如何避免重构带来的危险
- 如何避免重构带来的危险
- 如何避免重构带来的危险
- SQL大数据量查询的优化
- js---基本类型
- JAVA调用脚本并传输流数据(java调用rrdtool绘图并传输到页面展示)
- 【mysql连接池】之php+sqlrelay+mysql实现连接池及读写负载均衡 .
- 系统分析师书籍推荐
- 避免参数嗅探带来的资源消耗
- struts2防止重复提交方法
- sql server 中使用OBJECT_ID 总结
- package与存取权限
- DirectX 9.0 C++ 教程 字体 迟到的helloworld
- Fedora下解压缩的相关问题
- java环境变量配置
- visual studio内置“iis”组件提取及二次开发
- 2001-2004年上午试题知识点分布