我使用dapper-dot-net作为一个ORM,它产生以下慢执行(1700ms)的sql代码.
exec sp_executesql N'SELECT TOP 5 SensorValue FROM "Values" WHERE DeviceId IN (@id1,@id2) AND SensorId = @sensor AND SensorValue != -32768 AND SensorValue != -32767',N'@id1 bigint,@id2 bigint,@sensor int',@id1=139,@id2=726,@sensor=178
当我通过删除参数修改此代码时,查询执行速度快(20ms).这些参数的缺乏是否真的会带来很大的区别呢?
exec sp_executesql N'SELECT TOP 5 SensorValue FROM "Values" WHERE DeviceId IN (139,726) AND SensorId = 178 AND SensorValue != -32768 AND SensorValue != -32767'
解决方法
添加选项(RECOMPILE)到最后
... AND SensorValue != -32767 OPTION (RECOMPILE)
我怀疑你正在经历“参数嗅探”
如果是这样,我们可以留下OPTION或考虑替代品
更新1
以下文章将向您介绍“参数嗅探”http://pratchev.blogspot.be/2007/08/parameter-sniffing.html
我建议你知道ins和out,因为它会使你更好地理解sql server内部(可以咬).
如果你明白了,你会知道,如果语句被执行得很多,那么与选项重新编译的权衡可能会降低性能.
我个人添加选项重新编译后,我知道根本原因是参数嗅探,并留下它,除非有性能问题.重写语句以避免错误的参数嗅探导致意图丢失,从而降低可维护性.但有些情况下,重写是合理的(使用好的评论,当你这样做).
更新2
关于这个问题的最好的阅读在第32章中
“参数嗅探:你最好的朋友,除非不是”由GRANT FRITCHEY
推荐