【发布时间】:2020-05-08 22:12:59
【问题描述】:
我在表上的两个字段上有一个 PK(UtilityId、int 和 ACCT_NO varchar(100)) 我真的不知道订单是否有区别,但这是代码(首先是 UtilityId):
ALTER table AccountAddress
ADD CONSTRAINT [PK_AccountAddresses] PRIMARY KEY CLUSTERED (UtilityId,ACCT_NO)
如果我想在 UtilityId 上查询表,那么在 UtilityId 上创建索引是否有益(也许我不需要这样做,因为系统定义了一个 PK——凭借该索引已经存在)。
相反,如果我想查询 ACCT_NO,它是索引定义中的第二个字段,那么在 ACCT_NO 上创建索引是有益的,还是不是真的?
【问题讨论】:
-
1) 不,索引是分层的。服务器已经可以通过查找找到具有该值的任何行。 ACCT_NO 不是这种情况,服务器必须搜索所有索引记录以查找其中哪些包含谓词作为下一个值。
-
2) 是的,取决于查询。使用索引仍然意味着加载数据。根据查询和统计数据,服务器可能会决定使用 PK 更便宜。例如,如果您通过 PK 连接两个表,则无论如何都会使用 PK 索引。
-
我在第 1 点上不同意你的观点。某些查询例如:
SELECT COUNT(*) FROM AccountAddress可能会受益于狭窄的非聚集索引(即使在复合键中的一列上),因为 SQL Server 会选择最小的索引。这是一个很小的边缘案例,但在某些情况下这肯定是相关的。 -
这个问题的一般答案总是“视情况而定”。如果你想知道,那就去做并比较计划。很大程度上取决于您使用的查询。特定索引可能会使特定查询受益,但每个索引都有成本。如果“好处”很小和/或很少实现,这是否超过了用于它的空间成本和保持其最新的引擎成本(以及重新索引、重新组织、生成统计数据等的维护成本) .)?
-
请注意,非唯一非聚集索引在物理上存储为唯一非聚集索引,其余聚集索引键添加为尾随索引列。因此,UtilityId 上的索引存储为 (UtilityId,ACCT_NO) 上的索引,(ACCT_NO) 上的索引存储为 (ACCT_NO,UtilityId) 上的索引。
标签: sql-server indexing clustered-index non-clustered-index