升序键在 SQL 2016(新 CE)中执行错误计划,替代 TF 4139 等?

6 sql-server sql-server-2016 cardinality-estimates

SQL Server 2016 中的新基数估计器 (CE) 有一个不幸的回归,它严重影响了我们的部署。有问题的查询是一个普通的 Hibernate 生成的更新;然而,更新的表也是索引视图的一部分。这是一个单行更新,通常也会影响索引视图中的 ~5 行。

我已经设法将问题缩小到 2.5M 表的 PK 列的基数估计,如果首先针对该列的当前统计信息中的 PK 值编译查询,一切正常,并且生成了最佳计划.

如果 PK 较新,id est 在统计范围之外,CE 130 会生成一个非常次优的计划,基本上估计整个索引视图将受到更新的影响。对于 CE 120 或 CE 70 而言,这对我们来说从来都不是问题,这两个估算器都能生成良好的计划。有问题的领先列被“标记”为 UNKNOWN。

然而,我发现有几个跟踪标志(2388-90、4139)可用于旧的查询规划器,但这些对 CE 120+ 没有影响。

是否有任何更新的设置或跟踪标志可以调用以确保每次都能找到正常的查询计划?

我已经尝试过 TF 9481 来强制使用旧的 CE,然后它工作得很好,但这很难与 Hibernate 结合(很难将提示注入查询,我真的不想在 Hibernate 的内部结构中胡思乱想)。我还尝试了 TF 4199 和最新的 CU,但无济于事。

Bre*_*zar 2

如果所有这些都是真的:

  • 您只需要修复相对有限数量的查询(几十到几百)
  • 您确切地知道它们是什么,并且可以获得 T-SQL
  • 它们不会改变(最终用户无法动态构建自己的,或添加搜索条件)
  • 你可以保证他们不会改变
  • 您可以控制它们在哪个上下文中执行(例如,它们不在具有指向用户数据库的完全限定对象名称的 TempDB 中执行)
  • 它们位于有限数量的数据库中(与软件即服务方法相反,在软件即服务方法中,每个客户端都位于自己的数据库中,并且您希望修复所有数据库中的所有查询)

那么计划指南就是一个很好的解决方案。只需知道,如果您违反任何这些规则(例如查询开始更改),那么计划指南将不起作用。