新基数估算器中的联接包含假设会降低查询性能

本文可帮助你解决在使用新的基数估算器编译查询时,SQL Server 2014 及更高版本中可能出现的性能问题。

原始产品版本:SQL Server
原始 KB 编号: 3189675

症状

请考虑以下情况:

  • 你使用的是 SQL Server 2014 或更高版本。
  • 运行包含联接和非联接筛选器谓词的查询。
  • 使用新的基数估计 (SQL Server) ( 新 CE) 编译查询。

在此方案中,查询性能会降低。

如果使用旧版 CE 编译查询,则不会出现此问题。

原因

从 2014 SQL Server 起,为数据库兼容性级别 120 及更高版本引入了新基数估算器 (新 CE) 。 新 CE 在估计不同运算符和谓词的基数时,更改了模型中由查询优化器使用的旧版 CE 中的几个假设。

其中一项更改与联接包含假设相关。

旧版 CE 模型假定用户始终查询存在的数据。 这意味着,对于涉及两个表的 equijoin 操作的联接谓词,联接列存在于联接的两侧。 如果存在针对联接表的其他非联接筛选器谓词,则旧版 CE 假定联接谓词和非联接筛选器谓词具有某种程度的相关性。 这种隐含相关性称为简单包含。

或者,新 CE 使用基本包含作为关联。 新的 CE 模型假定用户可能会查询不存在的数据。 这意味着,单独表上的筛选器谓词可能彼此不相关。 因此,我们使用概率方法。

对于许多实际方案,使用基本包含假设可以创建更好的估计值。 这反过来又会创建更高效的查询计划选项。 但是,在某些情况下,使用简单包含假设可能会提供更好的结果。 如果发生这种情况,在使用新 CE 而不是旧版 CE 时,可能会遇到效率较低的查询计划选择。

有关如何排查与新 CE 相关的问题的详细信息,请参阅从 SQL Server 2012 或更早版本升级到 2014 或更高版本后查询性能下降

解决方案

在 SQL Server 2014 及更高版本中,可以使用跟踪标志 9476 强制SQL Server使用简单包含假设,而不是默认的基本包含假设。 如果可以修改应用程序查询,更好的选择是在 SQL Server 2016 (13.x) SP1 之后使用查询提示ASSUME_JOIN_PREDICATE_DEPENDS_ON_FILTERS。 有关详细信息,请参阅 USE HINT。 例如:

SELECT * FROM Table1 t1
JOIN Table2 t2
ON t1.Col1 = t2.Col1
WHERE Col1 = 10
OPTION (USE HINT ('ASSUME_JOIN_PREDICATE_DEPENDS_ON_FILTERS'));

如果满足以下条件,则启用此跟踪标志或使用查询提示可以改进查询计划选择,而无需完全还原旧版 CE 模型:

  • 查询计划选择不理想,导致包含联接和非联接筛选器谓词的查询的整体性能下降。
  • 可以验证“联接基数”估计中的明显不准确, (,即实际行数与估计行数) 显著差异。
  • 使用旧版 CE 编译查询时,不存在这种不准确之处。

可以在会话级别或查询级别全局启用此跟踪标志。

注意

错误地使用跟踪标志可能会降低工作负荷性能。 有关详细信息,请参阅 提示 (Transact-SQL) - 查询