2017-08-14 24 views
1

我正在审查在我们的项目中创建的一些数据库表,并发现了这个问题。该表包含一个标识列(ID),该列是该表的主键,并且已使用此ID列定义了聚集索引。但是当我查看从该表中检索记录的SPROC时,我发现ID列在查询中从不使用,并且它们基于USERID列查询记录(此列不是唯一的),并且可以有多个记录相同的USERID。创建聚集索引是否有优势 - 如果我们不打算查询/搜索基于该列的记录?

所以我的问题是有没有任何优势/目的创建聚集索引,当我们知道记录不会被查询该列?

+2

PK列很可能是许多'JOIN's的目标,它们将从聚集索引中获益匪浅。 – Alejandro

回答

1

我会说你的餐桌是错误设计的。有人显然认为每个表都需要一个主键,主键是聚簇索引。如果该号码在任何地方都没有使用,那么添加一个系统生成的唯一号码作为标识符就会增加噪音。至少可以说,聚集索引中的噪声无益。顺便说一下,它们是不同的概念。主键是数据建模问题,这是一个逻辑概念。索引是一个物理设计问题。 SQL DBMS必须支持主键,但不需要任何索引,集群或否。

如果USERID是通常用于搜索表格的东西,它应该在聚簇索引中。聚集索引不必是唯一的,并且不必是主键。我会仔细查看数据,看看USERID和另一列(或两个或更多)的组合是否构成该行的唯一标识符。如果是这样,我会把这个主键(和聚集索引)作为第一列,并且将USERID作为第一列。如果查询分析显示许多查询只使用USERID而没有其他(用于存在测试),我可能会创建一个单独的索引,只是USERID

如果没有组合的列构成一个唯一的标识符,你有逻辑问题,就机智:什么行意味着?它代表真实世界的哪个方面?

关系模型的一个基本原则是关系中的元素(表中的行)是唯一的,每个标识的东西。如果两行相同,则它们识别相同的事物。删除其中之一意味着什么?他们是否仍然存在或不存在?如果是,第二排服务的目的是什么?

我希望能给你另一种思考聚簇索引和键的方法。如果您发现其他可以改进的表格,我也不会感到惊讶。

3

如果从未在WHEREJOIN子句中使用IDENTITY列,或者由外键引用,则可能USERID应该是集群主键。在那种情况下,我会质疑需要ID列。

聚簇索引的最佳选择很大程度上取决于表的查询方式。如果大多数查询都是USERID,那么它可能应该是唯一的聚簇索引(或聚簇唯一约束),非聚簇的列应该是。

请记住,聚簇索引键作为行定位符隐式包含在所有非聚簇索引中。这意味着非聚集索引可能更有可能覆盖查询和非聚集索引叶节点页面。

+0

这些是我添加USERID作为聚簇索引的关注点: 1. SQL服务器将添加uniquefier以使索引唯一。我读到它可能是一个性能约束? 2.也可以有很多的添加/删除的UID的 - 当它是一个聚集索引会不会是一个问题? – Isaiah4110

+1

我以为USERID是独一无二的。在这种情况下,SQL Server不会添加唯一性。我没有意识到性能问题是一个性能问题,除了4字节的额外存储空间外。增量聚簇索引键在插入性能方面具有优点和缺点。简短的回答是我不会过分关注非增量关键性能,除非您使用的主轴数量很少,并且预计有数亿用户。 –

相关问题