我一直在对执行批量插入的存储过程进行一些速度测试。它使用一些JSON作为参数,创建一个表变量,从目标表中已有的表变量中清除表变量中的所有重复项,然后将数据从表变量复制到目标表中。
在运行这些测试时,我看到一些截然不同的速度结果使我发疯。他们没有道理。我终于解决了这个问题,并且能够始终如一地重现它。
流程如下:
我一直在学习参数嗅探,尝试诸如将传入的参数转换为本地参数并添加WITH RECOMPILE
之类的事情,但是到目前为止,结果都是一样的。
如果这在生产中发生,那将是不可接受的。有人有什么想法吗?
谢谢!
答案 0 :(得分:4)
发表评论的时间有点长。
SQL Server首次运行时会将查询计划缓存在存储过程中。在您的情况下,第一次运行有一个空表,因此查询计划基于一个空表。对于您的问题,这似乎是一个不错的查询计划。
更改存储过程时,确实会产生一种效果:它会忘记缓存的查询计划。因此,将生成一个新计划,该计划将使用表的当前大小。
无论出于何种原因,第二个查询计划都比第一个查询计划差很多。我不知道为什么通常问题是相反的(空表上的查询计划更糟)。
我建议您弄清楚如何在有数据的情况下使查询具有正确的计划,并在每次运行时重新编译存储过程中的代码。那可能是过大了,但是却增加了一点开销。