SQL Server 2014索引优化:在索引中包含主键有什么好处?

时间:2016-08-02 15:09:55

标签: sql-server performance

运行查询后,SQL Server 2014实际查询计划显示缺少索引,如下所示:

 CREATE NONCLUSTERED INDEX IX_1 ON Table1 (Column1) INCLUDE
 (PK_Column,SomeOtherColumn)

缺少的索引建议在索引中包含主键列。该表是带有PK_Column的聚簇索引。

我很困惑,似乎我没有得到Clustered Index Primary Key的概念。

我的假设是:当表具有聚簇PK时,所有非聚簇索引都指向PK值。我对么?如果是的话,为什么缺少索引的查询计划要求我在索引中包含PK列?

2 个答案:

答案 0 :(得分:1)

<强>要点:
建议的索引无效,但它没有任何区别。有关详细信息,请参阅下面的测试部分..

经过一段时间的研究,发现answer here及以下声明令人信服地解释了缺失的索引特征..

  

他们只查看单个查询或单个查询中的单个操作。他们不会考虑已存在的内容或您的其他查询模式。

     

你仍然需要一个有思想的人来分析整体索引策略,并确保你的索引结构是高效和有凝聚力的。

所以提出这个问题,建议的这个指数可能是有效的,但不应该被视为理所当然。建议的索引对于执行特定查询的SQL Server非常有用,可以降低成本。

这是建议的指数..

 CREATE NONCLUSTERED INDEX IX_1 ON Table1 (Column1) 
        INCLUDE (PK_Column, SomeOtherColumn)

假设您有如下的查询..

select pk_column, someothercolumn 
from table 
where column1 = 'somevalue'

SQL Server尝试扫描窄索引(如果可用),因此在这种情况下,建议的索引将有所帮助..

如果你有一个如下所示的索引

,你还没有分享表的架构
create index nci_test on table(column1)

并且以下表格的查询将再次建议与问题

中所述相同的索引
select pk_column, someothercolumn 
from table 
where column1 = 'somevalue'

更新:
我有以下架构的订单表..

[orderid] [int] NOT NULL Primary key,
[custid] [char](11) NOT NULL,
[empid] [int] NOT NULL,
[shipperid] [varchar](5) NOT NULL,
[orderdate] [date] NOT NULL,
[filler] [char](160) NOT NULL

现在我又创建了一个以下结构的索引..

create index onlyempid on orderstest(empid)

现在当我查询下面的表格时

select empid,orderid,orderdate --6.3 units
from orderstest 
where empid=5

指数顾问会建议以下缺失指数。

CREATE NONCLUSTERED INDEX empidalongwithorderiddate
ON [dbo].[orderstest] ([empid])
INCLUDE ([orderid],[orderdate])--you can drop orderid too ,it doesnt make any difference

如果你能看到orderid也包含在上面的建议中

现在让我们创建并观察两种结构..

---根级别-------

仅供索引使用。
enter image description here

索引empidalongwithorderiddate
enter image description here

----叶级-------

仅供索引使用。
enter image description here

索引empidalongwithorderiddate
enter image description here

正如您所看到的,按照建议创建没有区别,即使它无效。

我假设索引顾问基于查询运行提出了建议,并且专门用于查询,并且它不知道涉及其他索引

答案 1 :(得分:0)

我不知道您的架构,也不知道您的疑问。只是猜测。

如果这个理论不正确,请纠正我。

你是对的,非聚集索引指向PK值。想象一下,你有一个存储在普通盘片硬盘上的大型数据库(例如千兆字节的文件)。让我们假设磁盘碎片化并且PK_index远离Table1索引保存物理。

想象一下,您的查询也需要评估Column1和PK_column。查询执行读取Column1值,然后读取PK_value,然后读取Column1值,然后读取PK_value ...

硬盘驱动器盘片从一个物理位置旋转到另一个物理位置,这可能需要一些时间。

在一个索引中拥有所有需求更有效,因为它意味着按顺序读取一个文件。