对于 SQL Server 缓存中的每个查询,plan_handle 始终不同

问题描述 投票:0回答:1

我正在评估一些计划缓存行为,这是我的场景。

我分别运行以下两个查询:

SELECT TOP 10 *
FROM dbo.Countries CT
LEFT JOIN dbo.Continents CN ON CT.ContinentId=CN.ContinentId
WHERE CountryId='AR'
SELECT TOP 10 *
FROM dbo.Countries CT
LEFT JOIN dbo.Continents CN ON CT.ContinentId=CN.ContinentId
WHERE CountryId='BR'

运行两个查询后,我得到了这个计划缓存视图:

Plan Cache View

我的理解是:

  • 不同的sql_handle:预期的
  • 不同的plan_handle:意外
  • 相同的query_hash:预期
  • 相同的query_plan_hash:预期

问题:我真的不明白为什么每次执行都会得到不同的 plan_handle,即使查询基本相同,并且 query_hash 和 query_plan_hash 确实匹配。这可能是什么原因?

这是两个缓存计划的比较: Comparison of cached plans

我明白声明中的差异,但我认为这不重要。否则,每个 sql_handle 总是有一个 plan_handle,因为它总是会改变。

已检查一些附加设置:

  • 优化级别:完全
  • 没有计划警告:(两者都是足够好的计划)
  • SET 选项匹配,两个查询都在同一个 SSMS 窗口中执行
  • 兼容等级:140
  • 针对 Ad Hoc 进行优化: false
  • 查询优化器修复:关闭
  • 旧版 CE:关闭
  • 没有数据库范围的配置
  • 参数化:简单
  • 资源调控器:已禁用

我检查了影响此行为的所有潜在属性,但没有运气。 我希望两个查询重用相同的计划,因此指向相同的 plan_handle。 难道我的期望不正确吗?

谢谢

sql-server query-optimization sql-execution-plan
1个回答
0
投票

我希望两个查询重用相同的计划,因此指向相同的 plan_handle。难道我的期望不正确吗?

您的期望是错误的。当您对 where 子句值进行硬编码时,文字值在计划优化时可用,因此不同的查询可能会得到不同的计划。

如果您没有在应用程序的设计中显式构建参数,您还可以依靠 SQL Server 查询优化器使用简单参数化的默认行为自动参数化某些查询。或者,您可以通过将 ALTER DATABASE 语句的 PARAMETERIZATION 选项设置为 FORCED,强制查询优化器考虑参数化数据库中的所有查询。

查询处理架构指南

© www.soinside.com 2019 - 2024. All rights reserved.