Please explain why the below differences between non clustered and clustered index. First I am running the below two select statements.
select *
from [dbo].[index_test2]
where id = 1 -- Nonclustered index on id column
select *
from [dbo].[index_test1]
where id = 1 -- Clustered index on id column
Execution plan shows "Table scan" for the first query and "Clustered index seek (clustered)" for the second query.
Then I am running below two statements.
select id
from [dbo].[index_test2]
where id = 1 -- Nonclustered index on id column
select id
from [dbo].[index_test1]
where id = 1 -- Clustered index on id column
Execution plan shows "Index seek (NonClustered)" for the first query and "Clustered index seek (Clustered)" for the second query.
You can see from the above two cases, when using clustered index it is going for "Index seek" but for in case of NonClustered index it shows "Table scan" (executed with *) and it shows "Index seek (NonClustered)" (executing with index applied column-id).
Can any one clarify why the NonClustered index reacting differently on both cases?
select *
is not covered by the non-clustered index, the index only contains theid
column, so a table scan is required to return all columns. In your second test caseselect id
is covered by the non-clustered index, so it can return rows directly from the index instead of performing a table scan. – AlwaysLearningSELECT *
, a typical nonclustered index won't be able to "cover" the query, e.g. provide all columns needed to be returned from the query. If SQL Server were to use the nonclustered index to seek the valueid = 1
, it would then have to do a (fairly expensive) Key lookup to get the other data from the actual data page. Doing this for a whole table just is too expensive - it is "cheaper" to just scan the whole table. That's one of the main reasons why you should NOT useSELECT *
everywhere - try to select ONLY those columns really needed – marc_s