索引扫描,索引查找和表扫描

时间:2014-08-22 09:05:23

标签: sql sql-server sql-server-2008

我有以下表格:

Create table Tab_with_Ix
(
    id int not null,
    name nvarchar(10),
    phone decimal(10,0)
)

我插入了一些记录:

insert into Tab_with_Ix 
values(1, 'Yogesh', 8855664452), (2, 'Vinay', 9977884455), (3, 'Sam', 9988554466)

现在,我在Tab_with_Ix上创建了一个非聚集索引:

CREATE NONCLUSTERED INDEX NCI_Ix on Tab_with_Ix(id)

现在,当我查询Tab_with_Ix

Select * 
from Tab_with_Ix
where id = 1

我得到了执行计划:

enter image description here

但是,当我使用以下查询时:

Select id 
from Tab_with_Ix 
where id = 1

我得到了执行计划:

enter image description here

我的问题是:为什么SQL Server一次使用表扫描,另一次是索引搜索?

1 个答案:

答案 0 :(得分:5)

如果您执行SELECT * - 您需要所有列 - 所以最后,SQL Server必须返回基表数据。在这种情况下,通常使用昂贵的密钥查找(或RID查找,如果不存在聚簇索引)进行表扫描(或聚簇索引扫描)而不是索引查找更便宜。

如果你有很多行,那么在某些时候SQL Server可以更有效地进行索引扫描和单个(或几个)键/ RID查找 - 所以如果你有几千行示例表 - 在某些时候(“引爆点”),SQL Server将开始使用您的非聚集索引。

在第二种情况下,当您执行SELECT id时,您只需要id列 - 并且该列位于索引页中 - 因此对该索引的索引搜索将为SQL Server提供所有这些它需要满足此查询 - 因此,索引搜索通常要快得多,并且优先于表扫描。

这是众多原因之一为什么你应尽量避免使用SELECT * FROM dbo.Table。使用SELECT *时,通常不使用非聚簇索引,而是使用表(或聚簇索引)扫描。