我有一个Oracle背景,并且在Oracle中使用每个表的“索引组织表”(IOT)听起来不合理,我从来没有真正看过这个。在SQL Server中,我工作的每个数据库在每个表上都有一个聚簇索引,这与IOT(概念上)相同。
为什么?到处使用聚簇索引有什么理由吗?在我看来,只有少数情况才会有好处。
由于
答案 0 :(得分:6)
聚簇索引与索引组织表不完全相同。使用物联网,每个字段必须参与物联网键。 SQL Server上的聚簇索引不必是唯一的,也不必是主键。
群集索引在SQL Server上广泛使用,因为几乎总会有一些自然排序使常用查询更有效。甲骨文中的物联网带来了更多的包袱,所以它们并没有那么有用,虽然它们可能更有用,然后它们通常被认可。
从历史上看,实际上旧版本的SQL Server 6.5或7.0版IIRC不支持行级锁定,只能锁定表或页面级别。通常,聚簇索引将用于确保写入分散在表的物理存储周围,以最大限度地减少页锁争用。但是,几年前SQL Server 6得到了支持,因此具有此问题的应用程序将仅限于罕见的遗留系统。
答案 1 :(得分:2)
如果没有聚簇索引,您的表将被组织为堆。这意味着插入的每一行都会添加到表末尾的数据页面中。此外,当行更新时,如果更新的数据大于之前,它们将被移动到表末尾的数据页。
什么时候没有聚集索引
如果您的表需要尽可能快的插入,但可能会牺牲更新和读取速度,那么没有聚簇索引可能对您有用。例如,如果您有一个用作队列的表,例如,许多插入稍后会被读取并移动到另一个表。
群集索引
聚簇索引根据聚簇索引中的列组织表中的数据。如果你集合错误的东西,例如uniqueidentifier,这可能会减慢速度(见下文)。
只要您的聚簇索引位于最常用于搜索的值上,并且它是唯一的并且不断增加,您就可以从聚簇索引中获得一些惊人的性能优势。例如,如果您有一个名为USERS的表,您通常在其中查找基于USER_ID的用户数据,那么在USER_ID上进行群集将加快所有这些查找的性能。这样可以简化为了获取数据而需要读取的数据页数。
如果你的聚集索引中有太多的键,这也会减慢速度。
聚簇索引的一般规则:
不要在任何varchar列上进行集群。
在INT IDENTITY列上进行聚类通常是最好的。
集中搜索您常用的内容。
在UniqueIdentifiers上进行群集
对于索引中的uniqueidentifier,它们效率极低,因为没有自然的排序顺序。基于索引的b树结构,在使用uniqueidentifier时,最终会出现极其碎片化的索引。在重建或重组之后,它们仍然非常分散。所以你最终得到一个较慢的索引,由于碎片,最终在内存和磁盘上真的很大。此外,对于uniqueidentifier的插入,您更有可能最终在索引上进行页面拆分,从而减慢插入速度。通常,唯一标识符对索引来说是个坏消息。
<强>摘要强>
我的建议是每个表都应该有一个聚簇索引,除非有充分的理由不这样做(即表作为队列运行)。
答案 2 :(得分:1)
我不知道为什么在大多数情况下你更喜欢聚集索引。使用群集,您可以免费获得一个您选择的索引。大多数情况下,这是主键(无论如何你可能都想强制执行!)。
堆主要用于特殊情况。
答案 3 :(得分:0)
我们在关系数据库中使用主键,并且通常通过这些主键建立关系。大多数人习惯将第一个字段命名为TableID并将其作为主键。当您在查询中连接两个或更多表时,如果使用聚簇索引,则会获得最快的结果。