我的系统中有一个名为“Orders”的现有表。OrderID 是该表中的主键——它是一个聚集索引。我为“OrderCompanyDetails”设计了一个新表,如下所示。1-to-1
它与订单表有关系。在新表中,OrderID 保留为聚簇主键。
只有当订单被批准时,数据才会被插入到新表中。所以插入到新表中的 OrderID 可能不按顺序。OrderID 10 可能会在 OrderID 5 之前插入,具体取决于首先批准的订单。
在 OrderID 上使用聚簇索引有助于我的查询。但是聚集索引位于以随机序列获取数据的列上。这是一个糟糕的索引设计吗?如果是,我是否应该添加一个名为 OrderCompanyDetailID 的新无意义标识列并将其作为聚集索引?
CREATE TABLE [dbo].[Orders]
(
[OrderID] [int] IDENTITY(1,1) NOT NULL,
[OrderType] [char](3) NOT NULL,
[StatusCD] [char](10) NOT NULL,
[CreatedOnDate] [datetime] NOT NULL CONSTRAINT [DF__Orders__CreatedOn] DEFAULT (getdate()),
CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED
(
[OrderID] ASC
)
)
CREATE TABLE [dbo].[OrderCompanyDetails](
[OrderID] [int] NOT NULL,
[POCompanyCD] [char](4) NULL,
[VendorNo] [varchar](9) NULL,
[CreatedOnDate] [datetime] NOT NULL CONSTRAINT [DF_OrderCompanyDetails_CreatedOn] DEFAULT (getdate()),
CONSTRAINT [PK_OrderCompanyDetails] PRIMARY KEY CLUSTERED
(
[OrderID] ASC
)
)
更新
最近阅读文章Ever-increasing clustering key – the Clustered Index Debate………….again!. 里面有评论
请记住——狭窄的、静态的、独特的、不断增加的——而且通常是代理键而不是自然键。
聚簇索引的建议是它们不断增加或不断减少,但这并不意味着它们必须如此。GUID 不会增加或减少,除非您使用顺序 GUID。大多数人不使用顺序 GUID。
如果您担心页面拆分会影响性能,请在需要页面拆分之前降低填充因子以容纳更多插入。如果 GUID 是聚簇索引,这也是 GUID 的建议(我不是说它应该是聚簇索引,我是说如果是的话)。请注意将它降低到多低,因为它会影响读取性能,这对您来说可能很重要,因为您提到 OrderID 上的聚集索引有助于您的查询。
答案是不一定。
索引的作用是插入后辅助查询表,你说这个索引就是干这个的。这种改进的成本是
索引在插入时有额外的开销成本——也就是说,新记录必须根据聚簇索引值在现有记录中排序。
维护索引和相关统计数据,以确保改进在初始实施后继续进行。这可能包括定期重建统计信息和/或索引。
如果维护和/或插入开销的成本大于在其操作的上下文中使用表进行选择所带来的性能增益带来的好处,则应重新考虑索引。
感谢您的回答。由于以下原因,我决定在我的表中添加一个代理键(作为标识列)
如果插入太重(并发),
ever increasing order
则会产生PAGELATCH_EX
等待问题。阅读PAGELATCH_EX waits and heavy inserts,其中提到了hash partitioning with a computed column
Bit Reversion注意:
Insert Hot Spot
如果工作负载涉及将数百个并发线程插入到表中,则会出现问题。另请阅读膝跳等待统计:PAGELATCH - Paul Randal
Insert Hotspot
,其中说明如下:Latch wait可以使用Advanced SQL Server performance tuning - Paul Randal中提到的DMV来分析,其中使用了
sys.dm_os_waiting_tasks
。另请参阅更新的 sys.dm_os_waiting_tasks 脚本PAGELATCH_EX - sqlskills将
Insert Hot Spot
和Page Split
作为 PAGELATCH_EX 的三个可能原因中的两个。