And*_*ndy 11 sql-server clustered-index
我有一个SQL Server 2014表,如下所示:
OrderId int not null IDENTITY --this is the primary key column
OrderDate datetime2 not null
CustomerId int not null
Description nvarchar(255) null
Run Code Online (Sandbox Code Playgroud)
我团队中的一些人建议聚集索引应该在OrderId
,但我认为CustomerId
+OrderId
将是更好的选择,原因如下:
WHERE CustomerId = @param
,而不是OrderId
CustomerId
是Customer
表的外键,因此使用聚集索引CustomerId
应该会加快连接速度CustomerId
不是唯一的,但OrderId
在索引中指定额外的列将确保唯一性(我们可以UNIQUE
在这两列上创建聚集索引时使用关键字,以避免没有唯一性的开销)CustomerId
并且OrderId
永远不会改变,所以这些行在初始写入后不会移动。CustomerId
进来时,聚集索引将能够提供所有列而无需任何额外工作。是否CustomerId
和OrderId
做法的声音是最好的选择给出了上述?或者,OrderId
它本身更好,因为它是一个单独的列,它本身就保证了唯一性?
目前,该表在 上有一个聚集索引,在 上有一个OrderId
非聚集索引CustomerId
,但它没有覆盖,所以由于我们使用的是 ORM 并且所有列都被请求,检索它们是额外的工作。所以在这篇文章中,我试图考虑使用更好的 CI 来提高性能。
我们数据库上的活动大约是 85% 的读取和 15% 的写入。
小智 5
我认为以CustomerID作为第一列的复合聚集索引键将是最好的,因为它在WHERE
几乎所有查询的子句中。
与增量键相比,可能会有更多的拆分(或者,如果您管理和维护填充因子以避免“坏”拆分,那么一段时间内可能会出现次优页面密度)。但是,客户查询的整体性能改进是显着的,因为避免了键查找。
根据您最关键的查询,OrderID或OrderDate可能最适合第二列。
例如,如果客户在登录网站后看到按时间顺序排列的最近订单列表,则OrderDate应该是下一个,以优化ORDER BY OrderDate DESC
.
如果您选择OrderID作为聚集索引,在CustomerID上使用非聚集索引,您仍然会得到拆分和碎片,只是在非聚集索引中。