8

我继承了一些用于 SQL SERVER 2005 数据库的数据库创建脚本。

我注意到的一件事是所有主键都是作为NON CLUSTERED索引而不是集群创建的。

我知道每个表只能有一个聚集索引,并且您可能希望将它放在非主键列上以提高搜索的查询性能等。但是,有CLUSTERED问题的表上没有其他索引。

所以我的问题是除了上述之外,是否有任何技术原因不在主键列上使用聚集索引。

4

5 回答 5

8

在任何“正常”数据或查找表上:不,我看不出任何原因。

在诸如批量导入表或临时表之类的东西上——这取决于。

令一些人惊讶的是,拥有一个好的聚集索引实际上可以加快诸如 INSERT 或 UPDATE 之类的操作。请参阅 Kimberly Tripps的出色 聚集索引辩论仍在继续......她在博客文章中详细解释了为什么会这样。

鉴于此:我认为没有任何正当理由不在任何 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

“索引女王”的优秀作品!:-)

于 2010-10-27T14:03:32.263 回答
6

聚集表与堆表

(关于主题的好文章www.mssqltips.com

HEAP 表(无聚集索引)

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

  • 具体数据不能快速检索,除非也有非聚集索引

  • 数据页未链接,因此顺序访问需要回溯到索引分配映射 (IAM) 页

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

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

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

聚簇表

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

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

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

  • 需要额外空间来存储聚集索引树 这些表在 sys.indexes 目录视图中的 index_id 值为 1

于 2010-10-27T14:10:41.463 回答
1

请阅读我在“无法直接访问聚集表中的数据行 - 为什么?”下的答案。, 第一的。特别是第 [2] 项警告。

创建“数据库”的人是白痴。他们有:

  • 一堆未规范化的电子表格,未规范化的关系表
  • PK 都是IDENTITY 列(电子表格相互链接;它们必须一个接一个地导航);整个数据库没有关系访问或关系权力
  • 他们有PRIMARY KEY,它产生UNIQUE CLUSTERED
  • 他们发现这会阻止并发
  • 他们删除了 CI 并将它们全部设为 NCI
  • 他们懒得完成逆转;为每个表提名一个替代(当前 NCI)成为新 CI
  • IDENTITY 列仍然是主键(它不是真的,但它在这个笨拙的实现中)

对于这种伪装成数据库的电子表格集合,完全避免 CI 变得越来越普遍,而只有 NCI 和堆。显然他们没有获得 CI 的力量或好处,但是地狱,他们没有获得关系数据库的力量或好处,所以谁在乎他们没有获得 CI 的力量(这是为关系数据库设计的,他们的不是)。他们看待它的方式,无论如何他们必须经常“重构”这该死的东西,所以为什么要麻烦。关系数据库不需要“重构”。

如果您需要进一步讨论此回复,请发布 CREATE TABLE/INDEX DDL;否则,这是一个浪费时间的学术争论。

于 2010-10-29T13:39:56.357 回答
0

这是另一个(是否已在其他答案中提供?)可能的原因(仍有待理解):

我希望,我稍后会更新,但现在更希望将这些主题联系起来

更新:
在理解聚集索引时我错过了什么?

于 2010-10-29T01:32:18.460 回答
0

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

当您开始使用 SQL 时,希望您会意识到在编写 SQL 语句时必须考虑系统性能。在非索引列上使用“ORDER BY”语句可能会使系统崩溃。使用聚集索引可能会给 CPU 带来不必要的负载。现在是 21 世纪,我希望我们在使用 SQL 编程时不必考虑系统性能,但我们仍然这样做。

对于一些较旧的编程语言,无论何时检索已排序的数据,都必须使用索引。我只希望这个要求今天仍然存在。我只能想知道有多少公司因为非索引数据上的 SQL 语句写得不好而更新了他们缓慢的计算机系统。

在我 25 年的编程生涯中,我从来不需要按特定顺序存储物理数据,所以也许这就是一些程序员避免使用聚集索引的原因。很难知道权衡是什么(存储时间,与检索时间),特别是如果您正在设计的系统有一天可能会存储数百万条记录。

于 2016-06-09T00:11:37.400 回答