创建聚簇索引是否有任何优势 - 如果我们不打算 query/search 获取基于该列的记录?
Is there any advantage in creating a clustered index - if we are not going to query/search for records based on that column?
我正在审查在我们的项目中创建的一些数据库 table,并遇到了这个问题。 table 包含一个标识列 (ID),它是 table 的主键,并且已使用此 ID 列定义了聚簇索引。但是当我查看从 table 中检索记录的 SPROC 时,我发现查询中从未使用过 ID 列,它们根据 USERID 列(该列不是唯一的)查询记录,并且可以是同一个 USERID 的多个记录。
所以我的问题是 advantage/purpose 在我们知道不会使用该列查询记录时创建聚集索引吗?
如果 IDENTITY
列从未在 WHERE
和 JOIN
子句中使用,或被外键引用,也许 USERID 应该是一个聚集主键。在那种情况下,我会质疑是否需要 ID 列。
聚集索引的最佳选择在很大程度上取决于 table 的查询方式。如果大多数查询是通过 USERID 进行的,那么它可能应该是一个唯一聚集索引(或聚集唯一约束)并且 ID
列是非聚集的。
请记住,聚簇索引键作为行定位符隐式包含在所有非聚簇索引中。这意味着非聚集索引可能更可能覆盖查询,因此非聚集索引叶节点页面更宽。
我会说你的 table 设计有误。有人显然认为每个 table 都需要一个主键,而主键就是聚簇索引。添加系统生成的唯一编号作为标识符只会增加噪音,如果该编号未在任何地方使用。聚簇索引中的噪音至少可以说是无益的。
顺便说一句,它们是不同的概念。主键是一个数据建模问题,一个逻辑概念。索引是一个物理设计问题。 SQL DBMS 必须支持主键,但不需要任何索引、集群索引或无索引。
如果 USERID
是通常用于搜索 table 的内容,它应该在您的聚集索引中。聚簇索引不必是唯一的,也不必是主键。我会仔细查看数据,看看 USERID
和另一列(或两列或更多列)的某种组合是否构成该行的唯一标识符。如果是这样,我会将其作为主键(和聚集索引),并将 USERID
作为第一列。如果查询分析显示许多查询仅使用 USERID
而没有其他(用于存在性测试),我可能会创建一个单独的索引 USERID
。
如果没有任何列的组合构成唯一标识符,那么您就有逻辑问题了,即:行是什么意思?它代表了现实世界的哪一方面?
关系模型的一个基本原则是关系中的元素(table 中的行)是唯一的,每个元素标识 某些东西。如果两行相同,则它们标识相同的事物。删除其中一个是什么意思?他们都认出的东西还在,还是不在?如果是,第二行的作用是什么?
我希望这能为您提供另一种思考聚簇索引和键的方式。如果您发现其他 table 也可以改进,我不会感到惊讶。
我正在审查在我们的项目中创建的一些数据库 table,并遇到了这个问题。 table 包含一个标识列 (ID),它是 table 的主键,并且已使用此 ID 列定义了聚簇索引。但是当我查看从 table 中检索记录的 SPROC 时,我发现查询中从未使用过 ID 列,它们根据 USERID 列(该列不是唯一的)查询记录,并且可以是同一个 USERID 的多个记录。
所以我的问题是 advantage/purpose 在我们知道不会使用该列查询记录时创建聚集索引吗?
如果 IDENTITY
列从未在 WHERE
和 JOIN
子句中使用,或被外键引用,也许 USERID 应该是一个聚集主键。在那种情况下,我会质疑是否需要 ID 列。
聚集索引的最佳选择在很大程度上取决于 table 的查询方式。如果大多数查询是通过 USERID 进行的,那么它可能应该是一个唯一聚集索引(或聚集唯一约束)并且 ID
列是非聚集的。
请记住,聚簇索引键作为行定位符隐式包含在所有非聚簇索引中。这意味着非聚集索引可能更可能覆盖查询,因此非聚集索引叶节点页面更宽。
我会说你的 table 设计有误。有人显然认为每个 table 都需要一个主键,而主键就是聚簇索引。添加系统生成的唯一编号作为标识符只会增加噪音,如果该编号未在任何地方使用。聚簇索引中的噪音至少可以说是无益的。
顺便说一句,它们是不同的概念。主键是一个数据建模问题,一个逻辑概念。索引是一个物理设计问题。 SQL DBMS 必须支持主键,但不需要任何索引、集群索引或无索引。
如果 USERID
是通常用于搜索 table 的内容,它应该在您的聚集索引中。聚簇索引不必是唯一的,也不必是主键。我会仔细查看数据,看看 USERID
和另一列(或两列或更多列)的某种组合是否构成该行的唯一标识符。如果是这样,我会将其作为主键(和聚集索引),并将 USERID
作为第一列。如果查询分析显示许多查询仅使用 USERID
而没有其他(用于存在性测试),我可能会创建一个单独的索引 USERID
。
如果没有任何列的组合构成唯一标识符,那么您就有逻辑问题了,即:行是什么意思?它代表了现实世界的哪一方面?
关系模型的一个基本原则是关系中的元素(table 中的行)是唯一的,每个元素标识 某些东西。如果两行相同,则它们标识相同的事物。删除其中一个是什么意思?他们都认出的东西还在,还是不在?如果是,第二行的作用是什么?
我希望这能为您提供另一种思考聚簇索引和键的方式。如果您发现其他 table 也可以改进,我不会感到惊讶。