【问题标题】:SQL Server Indexing -- Any benefits of creating a nonclustered index on composite key fields?SQL Server 索引——在复合键字段上创建非聚集索引有什么好处?
【发布时间】: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


【解决方案1】:

“普通”(SQL Server“关系”又名 B-Tree+)索引是一种向量。并且向量路径是键中所有列的复合,按键列表顺序。

搜索的效率取决于您尝试检索数据的“方式” 举个例子:

CREATE INDEX X ON T (A, B, C)

在这些情况下对于平等搜索将是有效的:

  • A 和 B 和 C
  • A 和 B
  • 一个

但是对于平等的搜索来说不会是有效的:

  • B
  • C
  • B 和 C

但是根据优化器的不同,如果基数估计器发现要返回的行数很少,它可以对索引进行扫描。

如果你只想查询 ACCT_NO,你可以创建一个特定的索引来提高性能。

索引的效率与查询中的谓词有关(WHERE 子句、连接的 ON 子句、HAVING、CASE……)。这称为“sargable”(搜索 ARGument ABLE)。 举个例子,无论你有什么索引,LIKE '%anyword%' 都不是 sargable。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-02
    • 2011-11-30
    • 1970-01-01
    • 2012-10-01
    • 2011-05-15
    • 1970-01-01
    相关资源
    最近更新 更多