假设我需要从 luTab 更新 myTab,如下所示

update myTab
  set LookupVale = (select LookupValue from luTab B
                                       where B.idLookup = myTab.idLookup)

luTab 由 2 列组成(idLookup(unique)、LookupValue)

哪个更可取:idLookup 上的唯一聚集索引,还是 idLookup 和 Lookupvalue 组合上的唯一聚集索引?在这种情况下,覆盖索引会产生任何影响吗?

(我最感兴趣的是SQL服务器)


尾声:

我在下面进行了 Krips 测试,其中 myTab 中有 2700 万行,luTab 中有 150 万行。关键部分似乎是索引的唯一性。如果索引指定为唯一,则更新将使用哈希表。如果未指定为唯一,则更新首先通过 idLookup(流聚合)聚合 luTab,然后使用嵌套循环。这要慢得多。当我使用扩展索引时,SQL 现在不再认为该 LookupValue 是唯一的,因此它会强制执行速度慢得多的流聚合嵌套循环路由

有帮助吗?

解决方案

我已经创建表和装载短短记录(50个左右的查找和15 MYTAB)。

然后,我已经试过各种索引选项。的索引查找上luTab总是具有29%的成本。

有趣的一点是,如果你在LookupValue列添加到luTab索引的执行计划展示了索引之后两个额外的步骤求:流聚合和断言。尽管成本为0%,这可能去了更多的数据。

我还试图上只是idLookup非聚集索引,并包括LookupValue作为“包括列”。这样,数据页不需要访问检索该列。这可能是你虽然执行计划没有显示出什么不同的选项(但他们没有流聚合/断言其一)。

-Krip

其他提示

首先:

  • 覆盖索引始终是非聚集的
  • 你应该始终有一个 PK 和一个聚集索引(SQL Server 上默认有相同的)

这两个概念是分开的

所以:

  • 如果唯一标识一行,您的 PK(集群)将是 idLookup
  • 覆盖索引将是 (idLookup) INCLUDE (LookupValue)

然而:

  • idLookup是PK(聚簇),所以不需要覆盖索引
  • 聚集索引(PK)通过聚集索引的性质隐式“覆盖”(简单地说,索引是最低级别的数据)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top