Ril*_*jor 10 sql-server execution-plan azure-sql-database query-performance
我们有一个带有 Key Lookup 的查询,它估计每次执行有数千行。据我了解,每次执行应该只有一行。我知道统计数据可能会产生误导,但优化器不明白主键是唯一的吗?
此查询中涉及的表具有以下形式的聚集主键:
/****** Object: Index [PK_Table_Name] Script Date: 6/16/2021 9:52:12 AM ******/
ALTER TABLE [dbo].[Table_Name] ADD CONSTRAINT [PK_Table_Name] PRIMARY KEY CLUSTERED
(
[Table_Name_ID] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)
据我了解,主键提供了对表中单行的唯一引用。
因此,对于它在非聚集索引中找到的每一行,它应该能够使用该索引对聚集索引的引用来检索它所需的单行,以满足其正在处理的行的其余查询过滤。(这是一个嵌套循环连接运算符。)
那么为什么它估计将近 4000 行将作为 Key Lookup 的一部分返回?(不是“对于所有执行”,大约 36,000,000 是 4000 和它期望从非聚集索引查找中得到的 9000 行的乘积。)
运行时统计数据显示该聚集索引查找有 2851 行和 2851 次执行,这正是我所期望的。
如果有帮助,这是在 Azure SQL 数据库中,带有@@version:
Microsoft SQL Azure (RTM) - 12.0.2000.8
Apr 29 2021 13:52:20
Copyright (C) 2019 Microsoft Corporation
Run Code Online (Sandbox Code Playgroud)
Jos*_*ell 10
查看 Paul White 的博客文章Cardinality Estimation Bug with Lookups以获得问题的答案:
在 SSMS 执行计划中,应用过滤谓词的键或 RID 查找的估计行数可能是错误的。
这个错误不会影响优化器的最终计划选择,但看起来确实很奇怪。
博文接着说,计划在 2020 年 8 月进行修复,以在新的 160 兼容级别下解决此问题:
计划在 SQL Server 2019(兼容级别 160)之后的版本中对此进行修复