【问题标题】:SQL Server: Key Lookup without Clustered IndexSQL Server:没有聚集索引的键查找
【发布时间】:2018-06-27 22:20:24
【问题描述】:

我有一个名为 Scan 的表,它只有两列:id (int)a (char)

它开始时没有任何索引。所以我在下面创建了一个非聚集索引链接

CREATE INDEX ix_id ON scan(id ASC)

所以我运行了这个选择:

SELECT id, a
FROM Scan
WHERE id = 1

这是执行计划:

如果我的表没有任何聚集索引,为什么我会得到键查找(聚集)?

【问题讨论】:

  • id 是否在您的表中标记为主键?如果是这样,SQL Server 自动在该列上创建了一个聚集索引 - 这是记录的默认行为。
  • 除非您有聚集索引,否则无法在聚集索引上进行键查找。所以要么你有一个 CI,要么可能是任何应用程序中的一个错误,它向你展示了这个计划。这些不是 SSMS 图标。
  • @marc_s,我没有任何主键。我创建了测试数据库,然后只是一个没有键或约束的简单表。然后我手动添加了snon-clustered index。
  • 当时可能 SQL Operations Studio 显示的图标有误。
  • 找到了这个github.com/Microsoft/sqlopsstudio/issues/391,这是一个来自 sql Operations Studio 的问题,说正在呈现密钥查找而不是 RID 查找。他们关闭了它,但我有最新版本,问题仍然存在。但你是对的,是一个错误

标签: sql-server database indexing clustered-index non-clustered-index


【解决方案1】:

非聚集索引的叶子节点只包含键列,所以除了键列之外的任何东西都被选中(在你的情况下是a),然后它需要执行Rid/key查找以从堆中提取数据/聚集索引

使用覆盖索引避免键查找

CREATE INDEX ix_id ON scan(id ASC) include (a)

通过这种方式a列也将与键列一起存储在您的索引中,因此将避免键查找

【讨论】:

  • 其实,如果表一个堆,那么执行计划中的操作将被称为“RID查找”——而不是“键查找(集群)”
  • 但是对于只有两列的表,添加 覆盖索引 似乎有点.....多余 - 你不觉得吗?同意 - 在订单情况下,这完全有道理 - 但是在这里??
  • @marc_s 我猜 OP 试图以简化的方式显示问题。但如果它只是两列,那么是的
  • 没错,我正在尝试简化问题。但是我没有任何类型的聚集索引,不应该只在聚集索引上调用 key Lookup 吗?
【解决方案2】:

如果我的表没有任何关键字,为什么我会得到一个 Key Lookup(集群) 聚集索引?

你没有。这可能是 SQL Operations Studio 使用的 html-query-plan 库中的一个错误。

Paste The Plan 网站 (example) 上也可以看到同样的问题。

如您所知(因为您发现了它!)错误报告 is here

【讨论】:

  • 谢谢你!现在我试图理解为什么他们关闭了这个问题,但最新版本的问题仍然存在,哈哈
  • 这个开源项目看起来在 23 天前有一个相关的提交(重构 Key Lookup 和 RID Lookup 的逻辑)。 github.com/JustinPealing/html-query-plan/commit/… 也许它还没有进入发货的产品。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-12
  • 2012-01-10
  • 1970-01-01
  • 1970-01-01
  • 2014-08-27
  • 1970-01-01
相关资源
最近更新 更多