我有一个动态的SQL。运行大约需要4分钟。如果我改为使用SQL的输出并运行它,则需要大约20秒。为什么会出现差异?我知道在动态版本中构建SQL会花费一些时间,但我无法想象它的价格昂贵。
有人有什么想法吗?这两个查询应该是相同的,所以我怀疑它是查询计划缓存的奇怪之处,但并不是真的有很多想法。
修改 通过输出来澄清我的意思。
在动态SQL中,最后一行是
EXEC sp_executesql @myQuery,
N'@var1 INT,
@var2 INT,
@var2 INT',
@var1,
@var2,
@var3
我获取了myQuery的值并将其放在自己的SQL文件中。那是在20秒运行,而使用执行的动态需要4分钟。
编辑2 我删除了参数。我得到了有趣的结果。动态SQL语句看到了性能提升。硬编码版本的性能受到了极大的打击。现在两者差不多。
答案 0 :(得分:7)
我将假设您使用的是Microsoft SQL Server(您只标记了您的问题“sql”)。
在某些情况下,不同的参数值会导致不同的优化计划。然后缓存该优化计划,并在下次使用不同参数值执行查询时使用。但优化计划不是后续参数值的最佳计划。
这是一篇关于此问题的文章和一些解决方法: https://www.simple-talk.com/sql/t-sql-programming/parameter-sniffing/
是的 - 在某些情况下,与没有参数化运行相同的查询相比,使用参数化查询会导致性能下降。
如果您无权发布您的代码,我们无法知道这是否适用于您的情况。
我尊重你不能这样做 - 通过张贴到StackOverflow,you implicitly license your code and/or words with a Creative Commons license。但是,除非他们同意,否则分享由雇主拥有的代码是不合适的。
答案 1 :(得分:5)
正如Bill Karwin所说,这可能是一个“参数嗅探”问题。尝试包括以下行:
OPTION (RECOMPILE)
在SQL查询结束时。
这里有一篇文章解释了什么参数嗅探:http://blogs.technet.com/b/mdegre/archive/2012/03/19/what-is-parameter-sniffing.aspx
答案 2 :(得分:4)
如果您正在使用SQL Server 2008或更高版本,请使用OPTIMIZE FOR UNKNOWN查询提示。将以下内容添加到动态查询的末尾:
OPTION (OPTIMIZE FOR (@var1 UNKNOWN, @var2 UNKNOWN, @var3 UNKNOWN))
尝试更改或输出三个输入@ var1,@ var2和@ var3。是的,如果查询优化器尝试对真正临时的事物使用统计信息,那么它确实会非常昂贵。如果您的一个或多个变量是可预测的,请针对特定值进行优化,并针对未知来优化剩余变量。请查看此链接以获取更多详细信息。
要清楚,这可能是一个参数嗅探问题,如上面的ninjaPixel所示。 OPTIMIZE FOR UNKNOWN
可以为您提供比重新编译每个查询更好的结果,因为查询优化器依赖于统计信息来进行编译。
答案 3 :(得分:2)
为动态查询添加评论。 输入变量@ var1,@ var2,@ var3等的注释值
看起来像:
EXEC sp_executesql @myQuery,
/* var1Value, var2Value, var3Value */
N'@var1 INT,
@var2 INT,
@var2 INT',
@var1,
@var2,
@var3
因此,执行计划将仅针对不同的值重新编译。