外键 VS 主键上的聚集索引
Posted
技术标签:
【中文标题】外键 VS 主键上的聚集索引【英文标题】:Clustered Index on Foreign Key VS Primary Key 【发布时间】:2017-08-20 03:32:31 【问题描述】:表结构(SalesPersonProduct)
SalesPersonProductId INT (PK, Clustered)
SalesPersonId INT (FK - non-unique - Nullable)
ProductId INT (FK - non-unique - Nullable)
AreaId INT (Not Null)
DistributionType INT (Not Null)
ItemOrder INT (Not Null)
ItemSize INT (Not Null)
场景:SalesPersonId 是非唯一的,实际上此列中可能有 70 - 80 个重复项。但是,这是唯一用于读取和连接的列,并且当前没有索引。
SalesPersonProductId 仅用作 PK 以供参考,对这些表的更新是通过 PK 处理的,但很少见。将行添加到表后,PK 或 SalesPersonId 都不会更新。
问题: 假设我不能对表结构或相关表进行任何更改。将现有的 PK 更改为非聚集索引并将 SalesPersonId 添加为聚集索引是否会更好?或者只是将 SalesPersonId 添加为标准的非聚集索引?
我知道在幕后,许多非唯一值将获得唯一标识符 - 但是此列几乎用于所有读取,我希望这将提供最佳性能增益,尽管以额外的成本为代价字节现在用于保留这个新聚集索引的“唯一性”。
【问题讨论】:
成本不是额外的字节,而是由于集群键没有每个增加的模式而导致的写入页面拆分。如果有很多写入,您可能会发现非聚集索引(可能将最常见的列包含为非键列)更好。如果您主要阅读并读取足够多的数据,SalesPersonID
上的非聚集索引实际上会导致您出现问题,那么您可能会发现将SalesPersonId
作为您的聚集键可以获得净收益。长话短说,这取决于。做一些测试。
除了SalesPersonProductId
之外,还有什么能让你的行独一无二的吗?
(SalesPersonId, ProductId) 是唯一的吗?
@AntonínLejsek - 否
@SqlZim - 可能是(SalesPersonId、ProductId、AreaId)
【参考方案1】:
你错过了一件事。
i) 哪个列将最常用于搜索,即在 where 子句中使用最多。如果 SalesPersonId 然后将其设为 CI,或者您可以将 SalesPersonId 和 productid 都设为 CI。
ii)如果您可以更进一步,那么还可以计算索引的选择性
https://www.google.co.in/webhp?sourceid=chrome-instant&rlz=1C1CHMO_enIN556IN556&ion=1&espv=2&ie=UTF-8#q=how+to+find+selectivity+of+an+index
【讨论】:
以上是关于外键 VS 主键上的聚集索引的主要内容,如果未能解决你的问题,请参考以下文章