我们有一个带有 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
据我了解,主键提供了对表中单行的唯一引用。
因此,对于它在非聚集索引中找到的每一行,它应该能够使用该索引对聚集索引的引用来检索它需要满足对它所作用的行的其余查询过滤所需的单行。(这是一个嵌套循环连接运算符。)
那么为什么它估计将近 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
查看 Paul White 的博客文章Cardinality Estimation Bug with Lookups以获得您问题的答案:
该博客文章继续说,计划在 2020 年 8 月进行修复,以在新的 160 兼容级别下解决此问题: