我使用dapper-dot-net作为ORM,它会产生以下缓慢执行(1700毫秒)的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
当我通过删除参数来修改此代码时,查询将以极快的速度(20毫秒)执行。缺少这些参数是否应该造成很大的不同,为什么?
exec sp_executesql N'SELECT TOP 5 SensorValue FROM "Values" WHERE DeviceId IN (139,726) AND SensorId = 178 AND SensorValue != -32768 AND SensorValue != -32767'
在末尾添加OPTION(RECOMPILE)
... AND SensorValue != -32767 OPTION (RECOMPILE)
我怀疑您正在经历“参数嗅探”
如果是这种情况,我们可以将其留给OPTION或考虑替代方案
更新1
以下文章将向您介绍“参数嗅探” http://pratchev.blogspot.be/2007/08/parameter-sniffing.html
我建议您先了解它的来龙去脉,因为它会使您更好地了解sql server内部(可能会咬人)。
如果你了解它,你就会知道,用重新编译选项的权衡可如果执行的语句是一个性能下降非常频繁。
在我知道根本原因是参数嗅探之后,我亲自添加了选项重新编译,除非有性能问题,否则将其保留。重写语句以避免错误的参数嗅探会导致意图丧失,从而降低了可维护性。但是在某些情况下,重写是合理的(这样做时请使用良好的注释)。
更新2
我在该主题上获得的最佳阅读是在第32章中“ GRANT FRITCHEY撰写的“参数嗅探:您最好的朋友……”
推荐。