我有一项任务是建议对查询执行计划进行一些改进。该表是:
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结构中获取列。
答案 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)
sql server选择此索引,因为它满足所有列/索引是窄的。还记得sqlserver优化器是基于成本的