动态SQL比硬编码等效的时间长得多

时间:2013-03-15 19:04:09

标签: sql sql-server

我有一个动态的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语句看到了性能提升。硬编码版本的性能受到了极大的打击。现在两者差不多。

4 个答案:

答案 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。是的,如果查询优化器尝试对真正临时的事物使用统计信息,那么它确实会非常昂贵。如果您的一个或多个变量是可预测的,请针对特定值进行优化,并针对未知来优化剩余变量。请查看此链接以获取更多详细信息。

https://blogs.msdn.microsoft.com/sqlprogrammability/2008/11/26/optimize-for-unknown-a-little-known-sql-server-2008-feature/

要清楚,这可能是一个参数嗅探问题,如上面的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

因此,执行计划将仅针对不同的值重新编译。