在SQL Server 2005中不建立聚集索引的原因

8
我收到了一些用于创建 SQL SERVER 2005 数据库的脚本。
其中一个问题是,所有主键都被创建为NON CLUSTERED索引而不是聚集索引。
我知道每个表只能有一个聚集索引,你可能想将它放在非主键列上以提高查询性能等。但是,在这些表中没有其他CLUSTERED索引。
所以我的问题是除了以上原因外,是否存在不在主键列上使用聚集索引的技术原因?

1
我注意到的一件事是,所有的主键都被创建为非聚集索引,而不是聚集索引。为什么我观察到的与此相反? - Gennady Vanin Геннадий Ванин
@vgv8 - 为了澄清,我继承的数据库脚本明确设置键为非聚集。 - AJM
1
我仍然无法理解这个问题:https://dev59.com/tFHTa4cB1Zd3GeqPP0B8,尽管我不明白为什么/何时需要聚集索引。 - Gennady Vanin Геннадий Ванин
5个回答

8
在任何“普通”的数据或查找表上,我看不出有任何理由。
在类似批量导入表或临时表之类的东西上,这取决于具体情况。
对一些人来说,令人惊讶的是,拥有一个好的聚集索引实际上可以加速INSERT或UPDATE等操作。请参阅Kimberly Tripp的The Clustered Index Debate continues....博客文章,在其中她详细解释了为什么会出现这种情况。
在这种情况下:我看不出在任何SQL Server表上都没有一个良好的聚集索引(狭窄、稳定、唯一、递增= INT IDENTITY 最明显的选择)没有任何有效的理由。
要深入了解如何以及为什么选择群集键,请阅读Kimberly Tripp在这个主题上的所有优秀博客文章: http://www.sqlskills.com/BLOGS/KIMBERLY/category/Clustering-Key.aspx http://www.sqlskills.com/BLOGS/KIMBERLY/category/Clustered-Index.aspx 来自“索引女王”的优秀信息! :-)

6

聚集表与堆表的区别

(在www.mssqltips.com上有一篇关于此主题的好文章)

堆表(没有聚集索引)

  • 数据没有按任何特定顺序存储

  • 除非也有非聚集索引,否则无法快速检索特定数据

  • 数据页未连接,因此顺序访问需要参考索引分配映射(IAM)页

  • 由于没有聚集索引,不需要额外时间来维护索引

  • 由于没有聚集索引,不需要额外空间来存储聚集索引树

  • 这些表在sys.indexes目录视图中具有index_id值为0

聚集表

  • 数据按照聚集索引键排序存储

  • 如果查询使用索引列,则可以根据聚集索引键快速检索数据

  • 数据页链接以实现更快的顺序访问,但根据INSERTS、UPDATES和DELETES维护聚集索引需要额外时间

  • 需要额外空间来存储聚集索引树

  • 这些表在sys.indexes目录视图中具有index_id值为1


1
请先阅读我在“无法直接访问聚集表中的数据行-为什么?”下的回答,特别是[2]警告。
创建这个“数据库”的人是白痴。他们有:
  • 一堆未规范化的电子表格,而不是规范化的关系表
  • 所有PK都是IDENTITY列(电子表格彼此链接;必须逐个导航),没有跨数据库的关系访问或关系能力
  • 他们有PRIMARY KEY,产生UNIQUE CLUSTERED
  • 他们发现这会防止并发
  • 他们删除了CI并将它们全部变成了NCI
  • 他们太懒了,没有完成反转;对于每个表,提名一个备用的(当前的NCI)成为新的CI
  • IDENTITY列仍然是主键(实际上不是,但在这个笨拙的实现中是)
对于那些伪装成数据库的电子表格集合,越来越普遍的做法是完全避免使用CI,只使用NCI和Heap。显然,它们没有获得CI的任何功能或优势,但是它们也没有获得关系型数据库的任何功能或优势,所以谁在乎它们没有获得CI的功能(CI是为关系型数据库设计的,而它们不是)。从他们的角度来看,他们必须每隔一段时间就要“重构”这个可恶的东西,所以为什么要费心呢?关系型数据库不需要“重构”。
如果您需要进一步讨论此响应,请发布CREATE TABLE / INDEX DDL;否则,这是一个浪费时间的学术争论。

你能提供任何关于“越来越普遍地避免使用CI”和“CI的力量或好处”的参考资料吗? - Gennady Vanin Геннадий Ванин
1
@vgv8:如果您需要进一步讨论此响应,请发布CREATE TABLE/INDEX DDL;否则这是一个浪费时间的学术争论。您从过去的经验中知道,关于MS的详细信息很少,这就是为什么专家有自己的方法,以及为什么人们会支付他们严重的费用。尝试使用Google。尝试StackOverflow。我发现了这个帖子,它恰好部分回答了您的问题。有一天,我会写一本书,那时您将拥有完整的参考资料。 - PerformanceDBA

0

0

在一些仍在使用的B树服务器/编程语言中,固定或可变长度的平面ASCII文件用于存储数据。当向文件(表)添加新的数据记录/行时,记录会(1)附加到文件末尾(或替换已删除的记录),并且(2)索引会被平衡。以这种方式存储数据时,您不必担心系统性能(就B树服务器返回指向第一个数据记录的指针而言)。响应时间仅受索引文件中节点数量的影响。

当您开始使用SQL时,希望您意识到每次编写SQL语句时都必须考虑系统性能。在非索引列上使用“ORDER BY”语句可能会使系统崩溃。使用聚集索引可能会对CPU造成不必要的负载。现在是21世纪了,我希望我们在编写SQL时不必考虑系统性能,但我们仍然需要考虑。

在一些旧的编程语言中,检索排序数据时必须使用索引。我只希望今天仍然存在这个要求。我只能想象有多少公司由于对非索引数据编写的糟糕SQL语句而更新了其缓慢的计算机系统。

在我25年的编程经验中,我从未需要将我的物理数据按特定顺序存储,因此可能这就是为什么一些程序员避免使用聚集索引的原因。特别是如果您设计的系统将来可能会存储数百万条记录,很难知道权衡是什么(存储时间与检索时间之间的平衡)。

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