应用程序对Sqlserver进行SQL查询使用与不使用参数对执行计划的影响

Sqlserver 会为sql语句生成相应的执行计划,然后将编译好的sql执行计划存储到缓存中,等下次再使用相同的sql语句的时候,如果执行计划使用的索引,还有相关的统计数据,还有相关的数据没有显著的更新发生,sqlserver将从缓存中直接取出执行计划来使用,以提高sqlserver的性能。
sqlserver可以自动将执行的sql语句进行参数化,并在缓存中存储一条prepared的执行计划。如果使用.net应用程序使用ado.net 来调用sql语句的话,如果不使用参数,如:select * from t1 where id > 3,则sqlserver除了生成前面的prepared执行计划,还会生成一个select * from t1 where id > 3的执行计划,如果下次查询select * from t1 where id > 5(同样sql语句没有此值在执行计划中),则sqlserver使用prepared的执行计划,然后再生成一条select * from t1 where id > 5的执行计划,当再调用select * from t1 where id > 3的时候,sqlserver将不再使用prepared的执行计划,而直接使用select * from t1 where id > 3的执行计划。
如果使用.net应用程序调用sql语句的时候,使用的是参数化的查询,则在sqlserver中只会生成一条prepared的参数化的执行计划,而不会生成具体值的sql执行计划,如果在其后的调用中参数名发生了变化,sqlserver也不会调用之前生成的prepared执行计划,而会生成一条新参数名的prepared执行计划。

使用参数的方式调用sql语句的话,它能保证生成一条使用参数的prepared执行计划,但如果参数数值比较固定的话,那就直接使用非参数化的查询方式会更为合适。但使用非参数化的方式,有的查询语句可能不会自动生成参数化的prepared执行计划,而且,如果使用的查询数值只是个别使用而且不太固定的话,那样的话就可能会在缓存中生成很多使用率极低的执行计划来占用缓存空间,所以在这种情况下,使用参数化的方式也许更为合适。其实使用非参数化的方式写的sql语句会有可能比使用参数化sql语句调用使用更为贴近的执行计划。总之具体情况具体分析。

以上描述的观查方法:
在sqlserver中,用一没用的非生产库,执行如下sql语句,会得到测试用数据库的相关缓存
select cacheobjtype,objtype,refcounts,usecounts,sql from sys.syscacheobjects c
inner join sys.sysdatabases d
on c.dbid=d.dbid where d.name='testdbname'
如果其中的缓存内容过多,可以执行
dbcc freesystemcache('all')把整个系统缓存给清了,这个会影响到其他的数据库应该,所以最好只在测试用sqlserver上使用。
然后在应用程序中执行使用参数和非参数化的sql语句,就可以在查询到的缓存中看到结果了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值