简体   繁体   English

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

[英]Index scan, Index seek and table scan

I have following table: 我有以下表格:

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

I inserted some records: 我插入了一些记录:

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

Now, I create a non-clustered index on Tab_with_Ix : 现在,我在Tab_with_Ix上创建一个非聚集索引:

CREATE NONCLUSTERED INDEX NCI_Ix on Tab_with_Ix(id)

Now, when I query the Tab_with_Ix : 现在,当我查询Tab_with_Ix

Select * 
from Tab_with_Ix
where id = 1

I get an execution plan as: 我得到一个执行计划:

在此输入图像描述

But, when I use the following query: 但是,当我使用以下查询时:

Select id 
from Tab_with_Ix 
where id = 1

I get an execution plan as: 我得到一个执行计划:

在此输入图像描述

My question is: why does SQL Server use a table scan once, and the other time, an index seek? 我的问题是:为什么SQL Server一次使用表扫描,另一次,索引搜索?

In case you do a SELECT * - you want all columns - so in the end, SQL Server must go back to the base table data. 如果您执行SELECT * - 您想要所有列 - 所以最后,SQL Server必须返回基表数据。 In such a case, often it's cheaper to just do a table scan (or clustered index scan) rather than an index seek with an expensive key lookup (or RID lookup, if no clustered index is present). 在这种情况下,通常使用昂贵的密钥查找(或RID查找,如果不存在聚簇索引)进行表扫描(或聚簇索引扫描)而不是索引查找更便宜。

If you have a lot of rows, then at some point it will become more efficient for SQL Server to do an index scan and a single (or a few) key/RID lookups - so if you have thousands of rows in your sample table - at some point (the "tipping point"), SQL Server will start using your nonclustered index. 如果你有很多行,那么在某些时候SQL Server可以更有效地进行索引扫描和单个(或几个)键/ RID查找 - 所以如果你的样本表中有数千行 - 在某些时候(“临界点”),SQL Server将开始使用您的非聚集索引。

In the second case, when you do SELECT id , you only want the id column - and that column is in the index page - so an index seek on that index will give SQL Server all that it needs to satisfy this query - therefore, an index seek is typically much faster and will be preferred over the table scan. 在第二种情况下,当您执行SELECT id ,您只需要id列 - 并且该列位于索引页中 - 因此对该索引的索引搜索将为SQL Server提供满足此查询所需的所有内容 - 因此,索引搜索通常要快得多,并且优先于表扫描。

This is one of the many reasons why you should try to avoid using SELECT * FROM dbo.Table as much as you can. 这是为什么你应尽量避免使用SELECT * FROM dbo.Table众多原因之一。 With a SELECT * , more often than not, nonclustered indexes are not used, and a table (or clustered index) scan is used instead. 使用SELECT * ,通常不使用非聚簇索引,而是使用表(或聚簇索引)扫描。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM