回答

收藏

集群与非集群

技术问答 技术问答 85 人阅读 | 0 人回复 | 2023-09-13

我对SQL(Server2008)的较低层次的了解是有限的,现在我们的DBA对此提出了挑战。让我解释一下这种情况:(我已经提到一些明显的陈述,希望我是对的,但是如果您发现有问题,请告诉我)。6 _" S: o: ?3 \. b6 I0 {
我们有一张桌子,上面放着人们的“法院命令”。创建表(名称:CourtOrder)时,我的创建方式如下:8 S7 l+ u  X: O3 O1 C7 c* {
CREATE TABLE dbo.CourtOrder! W! x' ]/ }2 \5 L0 x* F  a
($ m- c+ H& Y, R
  CourtOrderID INT NOT NULL IDENTITY(1,1), (Primary Key)
5 R9 m4 y% k  @1 e  PersonId INT NOT NULL,4 \' h5 ^; C. Y# E7 e9 H! x8 B
  + around 20 other fields of different types.
3 L  [0 [( ^7 [! O! @" {# a/ e)$ y8 p6 g; Q4 `8 q9 O3 |7 F9 L5 ^$ V
然后,我将非聚集索引应用于主键(以提高效率)。我的理由是,这是一个唯一字段(主键),应该像我们经常为索引的目的而对其进行索引,主要是出于选择的目的Select5 O! Q- _+ H: L9 x4 l
from table where primary key = ...& j* G* [. y) |0 |1 i, }  N, W
然后,我在PersonId上应用了CLUSTERED索引。原因是按照物理方式将特定人员的订单分组,因为绝大多数工作都在为一个人获取订单。所以,select
6 j; n; z$ _4 P8 Wfrom mytable where personId = ...0 ?. P  p* K* V* h/ J/ O  ?
我现在已经对此感到不安。有人告诉我,应该将聚簇索引放在主键上,而普通索引放在personId上。这对我来说似乎很奇怪。首先,为什么要在唯一列上放置聚集索引?什么是集群?当然这是在聚集索引上的浪费吗?我相信普通索引将用于唯一列。同样,对索引进行聚类将意味着我们无法对不同的列进行聚类(每个表一个,对吗?)。  `4 K; l+ T3 X
被告知我犯了一个错误的原因是,他们认为在PersonId上放置聚簇索引会使插入速度变慢。对于选择速度提高5%的情况,插入和更新速度将降低95%。那是正确和有效的吗?
; d5 Z* f7 [0 N- w9 A- n3 Q他们说,因为我们对personId进行了群集,所以当我们插入或更改PersonId时,SQL Server必须重新排列数据。
7 s4 w+ Z' ~/ t$ Q& s9 D所以然后我问,如果它这么慢,为什么SQL会有CLUSTERED
7 k; p. c6 I( T" o$ Q- `  k+ aINDEX的概念?像他们说的那样慢吗?我应该如何设置索引以获得最佳性能?我以为SELECT的使用比INSERT还要多…但是他们说我们在INSERTS上存在锁定问题…/ |0 K" ?, O  m& _
希望可以有人帮帮我。' q6 ?( W) C5 F# d3 C+ G7 }4 V
                ' d% B* A( f$ ]8 u
解决方案:9 c. I1 p: X# |4 U8 Z- h1 E
                $ q, b- p% T% @  B5 s0 ~; O3 G
1 w# Z' }3 C0 v/ o( L' G
! ?8 J; S# A9 ]) H9 W% w
                聚集索引与非聚集索引之间的区别在于,聚集索引 确定数据库中行的物理顺序9 X9 v9 C8 D" r
。换句话说,将聚簇索引应用于PersonId意味着表中的行将按物理顺序进行排序PersonId,从而允许在该索引上直接搜索到该行(而不是非聚簇索引,后者将您定向到该行的位置,再增加一个步骤)。
% \" k! q9 f% W4 V' p也就是说,主键不是聚集索引,但并非闻所未闻是 不寻常 的。方案的问题实际上与您所假设的相反:您希望聚集索引中的 唯一
- D3 {7 S5 f' A9 T; x* |值,而不是重复值。因为聚集索引确定行的物理顺序,所以如果索引位于非唯一列上,则服务器必须向具有重复键值的行添加背景值(在您的情况下,具有相同键值的任何行PersonId),这样组合后的值(键+背景值)是唯一的。
, y4 j" \/ c5 V1 L2 v8 |我只建议 不要! W2 e# Y9 b3 y8 R- ]  s
将代理键(您的CourtOrderId)列用作主键,而应使用PersonId和其他一些唯一标识列或一组列的复合主键。但是,如果这不可能(或不切实际),则将聚簇索引放在上CourtOrderId。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则