为什么只有索引扫描,哪里是RID?

时间:2017-10-20 08:44:26

标签: sql-server execution

我有一项任务是建议对查询执行计划进行一些改进。该表是:

CREATE TABLE [Contracts] (  [ContractId] [int] NOT NULL  
, [ContractNumber] [varchar](50) NOT NULL  
, [SignDate] [datetime2](7) NULL  
, [EndDate] [datetime2](7) NULL  
, CONSTRAINT [PK_con_Contracts] PRIMARY KEY CLUSTERED ([ContractId] ASC) ); 

CREATE INDEX IX_con_Contracts_ContractNumber ON [Contracts] (ContractNumber) INCLUDE (SignDate)

我做的一些价值观:

INSERT INTO Contracts VALUES (1,'12340','2017-10-02','2017-11-02')  
INSERT INTO Contracts VALUES (2,'12341','2017-10-02','2017-11-02')
INSERT INTO Contracts VALUES (3,'12342','2017-10-02','2017-11-02')
INSERT INTO Contracts VALUES (4,'12343','2017-10-02','2017-11-02')

现在我正在对它运行查询:

SELECT ContractId  
, ContractNumber  
, SignDate FROM Contracts 
WHERE ContractNumber = 12340

所有内容都是对非聚集索引的扫描。但是怎么了?该索引不包括输出中我需要的所有列。我以为会有一些RID操作符从antoher结构中获取列。

enter image description here

2 个答案:

答案 0 :(得分:3)

非堆表上的非聚簇索引存储聚簇键列以启用查找。此处,群集密钥位于ContractId,索引位于ContractNumber并包含SignDate - 因此,此索引包含满足查询所需的所有列。

答案 1 :(得分:3)

  

但是怎么样?该索引不包括输出中我需要的所有列。我以为会有一些RID操作符从antoher结构中获取列。

您的查询

SELECT ContractId  
    , ContractNumber  
    , SignDate FROM Contracts 
    WHERE ContractNumber = 1234

需要低于列

contractid,contractnumber,signdate

即使您的非聚簇索引只有合约编号和signdate,为了使其唯一,sql server也会在非聚簇键定义中添加聚簇索引键

下面是dbcc页面的输出,以显示

DBCC IND('test_log','Contracts ',-1)


dbcc traceon(3604)
DBCC PAGE (0, 1, 195488, 3)

enter image description here

sql server选择此索引,因为它满足所有列/索引是窄的。还记得sqlserver优化器是基于成本的