我在 SQL Server 2012 中有一个表,如下所示。RequisitionID 上有一个聚集索引——但此列不是唯一的。一个 RequisitionID 可以有多个 ProductID。
CREATE TABLE [dbo].[RequisitionProducts](
[RequisitionID] [int] NOT NULL,
[ProductID] [int] NOT NULL,
[Qty] [int] NOT NULL,
[VendorID] [int] NOT NULL,
[UnitAmount] [decimal](10, 2) NOT NULL,
CONSTRAINT [pk_RequisitionProducts] PRIMARY KEY NONCLUSTERED
(
[RequisitionID] ASC,
[ProductID] ASC
)
)
CREATE CLUSTERED INDEX [cidx_RequistionProducts] ON [dbo].[RequisitionProducts]
(
[RequisitionID] ASC
)
GO
我搜索了很多,发现聚簇索引可以是非唯一的——但仅限于有限的情况。唯一提到的合适场景是有Range Search的时候。在我的例子中,几乎所有查询都将仅基于 RequisitionID——并且不需要范围搜索。
我还应该添加 ProductID 以使聚簇索引唯一吗?优缺点都有什么?
您应该删除
cidx_RequistionProducts
并使主键聚集。为支持主键而创建的索引将在筛选时为您完成这项工作RequisitionID
。当一个索引足以完成工作时,我认为拥有两个索引没有任何好处。删除额外的索引将在更新表时节省磁盘空间和 IO 成本。
感谢您的评论
uniquifier
。SQL Server 在内部添加 uniquifier 以使聚簇索引唯一(如果不是的话)。所以我最好自己将 ProductID(它是 int)添加到聚簇索引中。用于测试此功能的 DBCC 命令在了解和检查 SQL Server 中的唯一标识符中提供 - Ken Simmons。
该表的使用场景是频繁插入。因此,我将引入一个代理键(标识列)并将其作为主键和聚簇索引。不断增加的聚簇键——聚簇索引争论…………又来了!