据我了解,聚集索引的一个优点是,如果它是索引列的一部分,则可以更快地在那里查找某些内容,因为这些行是“关闭”存储的。由于 SQL Server 自动将主键设置为“聚集索引”,因此将聚集索引用于像代理键这样没有意义的东西是否会消除此优势,而我应该将自然键设为聚集索引?
2 回答
这里没有正确或错误的答案,视情况而定。集群的优势,比如作为主键的 IDENTITY 列,而不是在其他东西上集群,包括:
- 消除“坏”页面拆分,因为不断增加的值总是插入到表/分区的“末尾”(这会引入“热点”——如果您以非常高的速率插入,这可能会成为一个问题)。
- 使用查找或扫描来查找行或范围时不需要查找 - 如果您使用非聚集索引来标识行,则可能需要查找来检索任何未覆盖的列。
- an
INT
是 4 个字节(如果使用数据压缩,则更少)。因此,当您有引用该表的子表时,主键非常有用,这样子表中的重复信息也很窄。将其聚集在一起并没有太大的影响,但使用自然键作为聚集索引然后使用非聚集代理键对子表执行连接似乎是一种手动的解决方案。在我见过的大多数解决方案中,代理是聚集的(并分布在整个模型中),并且自然键只是简单地设置为唯一的。
谁知道您是否有更好的聚类键候选者?我们不知道您的应用程序,甚至您为自然键考虑的数据类型。什么是数据模型?什么是自然键?有可能改变吗?它很大吗?真的是独一无二的吗?
顺便说一句,我喜欢认为 SQL Server 默认创建PRIMARY KEY
是CLUSTERED
因为 (a) 大多数表应该有一个聚集索引,并且 (b) 在大多数情况下,键应该是聚集的(但不是全部!)。
您希望聚集索引键中的正常属性是:静态、窄、递增和唯一。
通常自然键不会变窄和增加。
通常自然键不会是静态的(如电话号码),尽管它可能是唯一的。与 int 或 bigint 相比,它通常不会特别窄(如 GUID 或车牌)。
表是聚集索引或堆。
聚集索引是用于组织整个表数据的键的选择。它不是像非聚集索引那样的单独索引。
例如,如果代理键是 IDENTITY,则代理键通常是聚集索引的不错选择。
如果它是 GUID,则可能不是,除非它是 SEQUENTIALID。
您可以看到为什么您希望此聚集索引键是静态的,因为您不希望数据行四处移动。每当密钥发生变化时,您还必须担心维护参照完整性。无论如何,我更喜欢任何用于引用的键都是静态的,因为级联更新/删除也会影响您的数据模型 - 真正的好处是,当您可以拥有一个静态代理而不必为所有这些重写而烦恼时?
如果要根据该键读取大块数据,则在其他键上进行聚类是有优势的。
要回答您的问题 - 我会说不,但发布您的表格设计和使用场景。