索引中的列顺序 - 插入性能

时间:2013-04-22 15:40:25

标签: sql-server indexing

我对索引列的顺序进行了一些研究,但我不是100%肯定所以请耐心等待! 我有下表:

CREATE TABLE [Valuation]
    (  
      [ValuationID] [int] IDENTITY(1, 1)
                          NOT NULL
                          CONSTRAINT [PK_Valuation] PRIMARY KEY ,  
      VersionID INT NOT NULL ,  
      AlphanumericIdentifier VARCHAR(255) NOT NULL,  
      ...  
      other columns  
      ...  
    )  

我在这个表上与VersionID和AlphanumericIdentifier上的其他人做了很多连接,所以我在其上放了一个索引:

CREATE NONCLUSTERED INDEX [IX_Valuation] ON [dbo].[Valuation]   
(
[VersionID] ASC,
[AlphanumericIdentifier] ASC
)

两个问题:

  1. 这些联接通常是针对特定的VersionID完成的,所以这是最具选择性的列,应该是索引中的第一个 - 正确吗?
  2. 插入总是针对单个版本完成,比上一个版本多1个。这应该可以减轻插入的性能,因为插入的行是一个可以添加到索引末尾的“块”。这是对的吗?
  3. 我很确定我1对,但是2是正确的吗?

    由于 乔

2 个答案:

答案 0 :(得分:1)

问题:

“这些连接通常是针对特定的VersionID完成的,因此这是最具选择性的列,应该是索引中的第一个。”

联接与它无关,除非连接被用作过滤器。  过滤器(Where子句谓词)和Sorting(Order By子句)使用索引。是否使用索引取决于有多少记录(行)满足过滤器。如果查询将返回表中的每一行(无where子句),那么很可能不会使用索引,因为查询优化器将决定(正确地)它只读取整个表而不是尝试使用一个索引。索引是具有多个级别的分层树结构。对于查询将返回的每一行,使用索引需要每个索引级别一个磁盘I / O.因此,如果查询将返回表中的所有1000行,并且索引中有五个级别,那么这将需要5000个IO。直接从表中读取数据而不是索引只需要1000个IO。

接下来,您的声明“这应该可以减轻插入时的性能,因为插入的行是可以添加到索引末尾的'块'”

仅当索引是聚簇索引时,此语句才为true。在您的架构中,聚集索引是主键(因为虽然您可以覆盖它,这是默认行为),它位于ValuationID上,而不是VersionId上。因此,插入 任何 记录的“块”,无论它们是否都具有相同的versionId,都将添加到索引的末尾,因为它们都将具有新的valuationId秒。

答案 1 :(得分:0)

是的,你们都是对的。

列应根据您查询的列进行排序,前导列是您经常或最常查询的列。

添加递增值为VersionID的行意味着不需要拆分中间页面。