8

我有一段动态的 SQL。运行大约需要 4 分钟。如果我改为获取 SQL 的输出并运行它,则大约需要 20 秒。为什么会出现差异?我知道在动态版本中构建 SQL 需要一些时间,但我无法想象它会那么贵。

有人有想法么?这两个查询应该是相同的,所以我怀疑查询计划缓存有点奇怪,但并没有太多的想法。

编辑: 通过输出来澄清我的意思。

在动态 SQL 中,最后一行是

EXEC sp_executesql @myQuery,
    N'@var1 INT,
    @var2 INT,
    @var2 INT',
    @var1,
    @var2,
    @var3

我取了 myQuery 的值并将其放入它自己的 SQL 文件中。运行时间为 20 秒,而使用 execute 的动态运行时间为 4 分钟。

编辑 2 我删除了参数。我得到了有趣的结果。动态 SQL 语句的性能得到了提升。硬编码版本对性能产生了巨大影响。现在两人差不多。

4

4 回答 4

7

我将假设您使用的是 Microsoft SQL Server(您只标记了您的问题“sql”)。

在某些情况下,不同的参数值可能会导致不同的优化计划。然后缓存该优化计划,并在下次使用不同的参数值执行查询时使用。但优化方案并不是后续参数值的最佳方案。

这是一篇关于这个问题和一些解决方法的文章: https ://www.simple-talk.com/sql/t-sql-programming/parameter-sniffing/

所以是的——在某些情况下,与在没有参数化的情况下运行相同的查询相比,使用参数化查询可能会导致性能下降。

如果您不能自由发布代码,我们无法知道这是否适用于您的情况。

我尊重你不能这样做——通过发布到 StackOverflow,你隐含地使用 Creative Commons license 许可你的代码和/或文字。但是,除非他们同意,否则共享您的雇主拥有的代码是不合适的。

于 2013-03-15T19:18:53.380 回答
5

正如比尔卡尔文所说,这可能是一个“参数嗅探”问题。尝试包括以下行:

OPTION (RECOMPILE)

在您的 SQL 查询结束时。

这里有一篇文章解释什么是参数嗅探:http: //blogs.technet.com/b/mdegre/archive/2012/03/19/what-is-parameter-sniffing.aspx

于 2013-10-23T13:27:50.940 回答
5

如果您使用的是 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与重新编译每个查询相比,它可以为您提供更好的结果,因为查询优化器依赖于统计信息来进行编译。

于 2016-12-27T16:11:39.107 回答
2

为您的动态查询添加评论。输入变量@var1、@var2、@var3 等的注释值。

它看起来像:

EXEC sp_executesql @myQuery,
    /* var1Value, var2Value, var3Value */    
    N'@var1 INT,
    @var2 INT,
    @var2 INT',
    @var1,
    @var2,
    @var3

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

于 2016-12-29T10:18:11.963 回答