指标表现,聚集索引 vs 非聚集索引

4
如果一张表只需要一个索引,那么聚集索引似乎是通常的选择。它更快,因为它不需要通过键引用回数据,而且也不像非聚集索引那样占用磁盘空间。
我的问题是,在有多个索引的情况下,是否最好完全删除聚集索引?这样做的逻辑是,如果您具有非聚集索引和聚集索引,则它们不再直接引用实际的数据行,而是引用聚集索引。因此,使用聚集索引作为代理会导致显着的性能损失。如果您认为需要在表上使用多个索引,那么似乎最好不要使用聚集索引。

1
你用的是哪个数据库?MySQL 还是 SQL Server? - Gordon Linoff
SQL Server。 - John Smith
请查看覆盖索引。这不是直接回答您的问题,但覆盖索引包含附加字段,并且可以提供信息,而无需从表中读取行。当然,这会带来存储惩罚。 - faester
@faester 覆盖索引是我提出问题的一个例外...尽管如此,它们仍然非常有用。如果索引覆盖了查询,则无需使用 RID(或者如果存在聚集索引,则不需要引用回聚集索引),因此这将是我的问题的一个例外。 - John Smith
1
使用逻辑RID而不是物理RID所带来的性能损失可能比您想象的要小。此外,如果将基表存储为堆,则没有索引可以使用它,而无需执行回溯查找(这很快就会变得昂贵)或在NCI本身中复制数据。这意味着它被存储两次并需要维护两次。 - Martin Smith
显示剩余2条评论
1个回答

0

如果表有适当的聚集索引,则删除它没有任何好处。
如果您有多个索引,则选择最佳的聚集索引候选项。
通常是您的PK。
创建PK时,默认情况下为聚集索引。
除非您有特定原因不使用它,否则PK是最佳的聚集索引候选项。

我不明白你的说法。

"如果您具有带有聚集索引的非聚集索引,则它们不再引用实际数据行,而是引用聚集索引。因此,似乎会有显着的性能损失。"

如果聚集索引在数据中,则引用聚集索引就是引用数据。数据按聚集索引物理组织。哪里会有显着的性能损失?

聚集索引设计准则

除了少数例外情况外,每个表都应该定义一个聚集索引

如果这些少数例外情况之一是另一个索引,则会指出它。
另一个非聚集索引不是没有聚集索引的原因。

非聚集索引结构

非聚集索引行中的行定位器可以是指向行的指针,也可以是行的聚集索引键,具体如下所述:

  • 如果表是堆表(即没有聚集索引),则行定位器是指向该行的指针。该指针由文件标识符(ID)、页码和页内行号构成。整个指针称为行标识符(RID)。
  • 如果表具有聚集索引或索引位于索引视图上,则行定位器是该行的聚集索引键。如果聚集索引不是唯一索引,则SQL Server通过添加一个名为唯一标识符的内部生成值来使任何重复键唯一。这个四字节的值对用户不可见。只有在需要将聚集键变为非聚集索引中使用的唯一键时才会添加它。SQL Server通过使用存储在非聚集索引叶行中的聚集索引键搜索聚集索引来检索数据行。

即使有主键,他们也可以选择使用RID。你认为聚集索引为什么会更慢?


1
好的,我会在回到工作岗位后测试它并与您联系。 RID并不总是更快,但如果表上已经存在一个聚集索引,则应该如此,因为它可以仅使用RID来识别记录,而无需运行整个聚集索引以查找记录。这很合乎逻辑。 - John Smith
1
原来事实证明,与我想的一样,非聚集索引在堆上的性能确实提高了20-30%。 - John Smith
1
@user3739391 我并没有删除我的聚集索引,但这真的很有趣。 - paparazzo
@NeerajPrasadSharma 这里有一项研究表明,非聚集索引在堆上的性能比聚集索引提高了20-30%。我自己没有测试过。http://dba.stackexchange.com/questions/9829/performance-of-non-clustered-indexes-on-heaps-vs-clustered-indexes/15048#15048 - John Smith
我刚刚进行了一个快速测试(SQL Server 2012),只是为了在需要查找时进行选择。时间几乎相同,但在RID查找中逻辑读取量几乎是关键查找的一半。 - Neeraj Prasad Sharma
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接