一尘不染

集群与非集群

sql

我对SQL(Server2008)的较低层次的了解是有限的,现在我们的DBA对此提出了挑战。让我解释一下这种情况:(我已经提到一些明显的陈述,希望我是对的,但是如果您发现有问题,请告诉我)。

我们有一张桌子,上面放着人们的“法院命令”。创建表(名称:CourtOrder)时,我的创建方式如下:

CREATE TABLE dbo.CourtOrder
(
  CourtOrderID INT NOT NULL IDENTITY(1,1), (Primary Key)
  PersonId INT NOT NULL,
  + around 20 other fields of different types.
)

然后,我将非聚集索引应用于主键(以提高效率)。我的理由是,这是一个唯一字段(主键),应该像我们经常为索引的目的而对其进行索引,主要是出于选择的目的Select from table where primary key = ...

然后,我在PersonId上应用了CLUSTERED索引。原因是按照物理方式将特定人员的订单分组,因为绝大多数工作都在为一个人获取订单。所以,select from mytable where personId = ...

我现在已经对此感到不安。有人告诉我,应该将聚簇索引放在主键上,而普通索引放在personId上。这对我来说似乎很奇怪。首先,为什么要在唯一列上放置聚集索引?什么是集群?当然这是在聚集索引上的浪费吗?我相信普通索引将用于唯一列。同样,对索引进行聚类将意味着我们无法对不同的列进行聚类(每个表一个,对吗?)。

被告知我犯了一个错误的原因是,他们认为在PersonId上放置聚簇索引会使插入速度变慢。对于选择速度提高5%的情况,插入和更新速度将降低95%。那是正确和有效的吗?

他们说,因为我们对personId进行了群集,所以当我们插入或更改PersonId时,SQL Server必须重新排列数据。

所以然后我问,如果它这么慢,为什么SQL会有CLUSTERED
INDEX的概念?像他们说的那样慢吗?我应该如何设置索引以获得最佳性能?我以为SELECT的使用比INSERT还要多…但是他们说我们在INSERTS上存在锁定问题…

希望可以有人帮帮我。


阅读 212

收藏
2021-05-05

共1个答案

一尘不染

聚集索引与非聚集索引之间的区别在于,聚集索引 确定数据库中行的物理顺序
。换句话说,将聚簇索引应用于PersonId意味着表中的行将按物理顺序进行排序PersonId,从而允许在该索引上直接搜索到该行(而不是非聚簇索引,后者将您定向到该行的位置,再增加一个步骤)。

也就是说,主键不是聚集索引,但并非闻所未闻是 不寻常 的。方案的问题实际上与您所假设的相反:您希望聚集索引中的 唯一
值,而不是重复值。因为聚集索引确定行的物理顺序,所以如果索引位于非唯一列上,则服务器必须向具有重复键值的行添加背景值(在您的情况下,具有相同键值的任何行PersonId),这样组合后的值(键+背景值)是唯一的。

我只建议 不要
将代理键(您的CourtOrderId)列用作主键,而应使用PersonId和其他一些唯一标识列或一组列的复合主键。但是,如果这不可能(或不切实际),则将聚簇索引放在上CourtOrderId

2021-05-05