计划缓存中的串行计划

use*_*827 2 performance sql-server optimization parallelism plan-cache query-performance

我有一个较早执行缓慢的查询。后来我发现它没有并行运行,这使得查询执行速度变慢。

查询涉及一个 big view,然后使用大量temp tablesand查询视图sub query

UDF从视图中删除了一个并使用inline functions并使用了一个标量TVF,然后它开始在parallel execution.

这几天一切顺利,有一天我注意到查询运行缓慢。于是查了一下执行计划,发现查询是在串行模式下执行的。我检查了查询的计划缓存,我看到了很多涉及该视图的缓存计划。我删除了不并行的计划,然后查询运行得很快。

现在我每天早上都这样做以强制查询并行运行。

额外细节:

  1. SQL Server 2016 标准版
  2. 查询通过 LINQ-SQL 从 dot net 应用程序生成。所以临时查询。

如何强制查询永远并行运行?

Bre*_*zar 9

乍一看,这听起来像是一个经典的参数嗅探问题。

SQL Server 为需要编译计划时调用的第一组参数构建执行计划,然后在一天中一遍又一遍地重用该计划。您可以看到它们是什么参数 - 当您查看串行计划时,右键单击 select 语句,然后进入属性。在属性窗口中,查找参数,然后查找编译值。这将显示哪些值会生成串行计划。

为了强制计划始终并行运行,您有几种不同的选择(Erland 在我上面链接的优秀帖子中介绍了其中的许多选项),包括:

  • 调整索引,使一切都得到一个更好的计划(要获得有关建议,请发布计划和服务器详细信息,如获取慢查询帮助中所述
  • 暂时,使用计划指南将并行计划固定在缓存中(但要知道如果查询更改单个字母,计划指南将无声地失败,因为它不再匹配查询)
  • 在计划中使用 OPTIMIZE FOR 提示将其引导至产生并行计划的值
  • 在 SQL Server 2016 中使用新的 ENABLE_PARALLEL_PLAN_PREFERENCE 提示

这只是一个快速的答案 - 但要了解更多信息,请阅读Erland 的精彩博文,Slow in the App,Fast in SSMS解释了一个查询如何获得不同的计划,以及如何解决它。

  • 由于这是 SQL 2016 Query Store 可以强制执行计划,这比使用计划指南更容易。 (2认同)