5

我有 Oracle 背景,在 Oracle 中为每个表使用“索引组织表”(IOT) 听起来不合理,我从未真正见过这一点。在 SQL Server 中,我处理的每个数据库在每个表上都有一个聚集索引,这与 IOT(概念上)相同。

这是为什么?是否有任何理由到处使用聚集索引?在我看来,它们只适用于少数情况。

谢谢

4

4 回答 4

6

聚集索引与索引组织表并不完全相同。对于 IOT,每个字段都必须参与 IOT 密钥。SQL Server 上的聚集索引不必是唯一的,也不必是主键。

聚集索引在 SQL Server 上被广泛使用,因为几乎总是存在一些自然排序,这使得常用查询更加高效。Oracle 中的 IOT 承载了更多的包袱,因此它们并没有那么有用,尽管它们可能比它们通常被认为的更有用。

从历史上看,SQL Server 6.5 或 7.0 IIRC 之前的真正旧版本不支持行级锁定,只能锁定在表或页面级别。通常会使用聚集索引来确保写入分散在表的物理存储周围,以最大程度地减少页面锁的争用。但是,SQL Server 6 几年前就停止了支持,因此存在此问题的应用程序将仅限于罕见的遗留系统。

于 2012-04-15T16:18:22.540 回答
2

如果没有聚集索引,您的表将被组织为一个堆。这意味着插入的每一行都添加到表末尾的数据页中。此外,随着行的更新,如果更新的数据比以前大,它们将移动到表末尾的数据页。

什么时候最好没有聚集索引

如果您的表需要尽可能快的插入,但会牺牲更新和读取速度,那么没有聚集索引可能适合您。一个例子是,如果您有一个用作队列的表,例如,许多插入稍后会被读取并移动到另一个表。

聚集索引

聚集索引根据聚集索引中的列组织表中的数据。如果你聚集在错误的东西上,例如唯一标识符,这可能会减慢速度(见下文)。

只要您的聚集索引位于最常用于搜索的值上,并且它是唯一的并且不断增加,您就可以从聚集索引中获得一些惊人的性能优势。例如,如果您有一个名为 USERS 的表,您通常在其中根据 USER_ID 查找用户数据,那么在 USER_ID 上进行集群将加快所有这些查找的性能。这只是减少了为获取数据而需要读取的数据页的数量。

如果您的聚集索引中有太多键,这也会减慢速度。

聚集索引的一般规则:

不要聚集在任何 varchar 列上。

在 INT IDENTITY 列上进行聚类通常是最好的。

根据您通常搜索的内容进行聚类。

基于 UniqueIdentifiers 的聚类

在索引中使用唯一标识符时,它们的效率极低,因为没有自然的排序顺序。基于索引的 b 树结构,在使用 uniqueidentifiers 时,您最终会得到极其碎片化的索引。在重建或重组后,它们仍然极为分散。因此,您最终会得到一个较慢的索引,由于碎片,最终在内存和磁盘上非常巨大。同样在 uniqueidentifier 的插入中,您更有可能在索引上出现页面拆分,从而减慢您的插入速度。通常,唯一标识符对索引来说是个坏消息。

概括

我的建议是每个表都应该有一个聚集索引,除非有很好的理由不这样做(即表作为一个队列运行)。

于 2012-04-15T16:53:55.410 回答
1

我不知道为什么大多数时候你更喜欢堆而不是聚集索引。使用聚类,您可以免费获得一个您选择的索引。大多数情况下,这是主键(您可能无论如何都想强制执行!)。

堆主要用于特殊情况。

于 2012-04-15T14:22:32.487 回答
0

我们在关系数据库中使用主键,通常关系是通过这些主键建立的。大多数人习惯将第一个字段命名为 TableID 并将其设为主键。当您在查询中加入两个或更多表时,如果使用聚集索引,您将获得最快的结果。

于 2012-04-15T13:13:43.377 回答