indexing - Why isn't SQL Server using my index? -
in our database have table 200.000 rows
create table dbo.usertask ( usertask_id int not null identity (1, 1), usertask_sequencenumber int not null default 0, usertask_identitat uniqueidentifier not null, usertask_subject varchar(100) not null, usertask_description varchar(500) not null, ..... ..... constraint [pk_usertask] primary key clustered ( [usertask_id] asc ) on [primary] ) on [primary]
i have created index on usertask_identitat
column with
create nonclustered index ix_usertask_identitat on dbo.usertask ( usertask_identitat )
executing following query, execution plan shows index on usertask_identitat
used query:
select usertask_id usertask usertask_identitat = @identitat order usertask_lastsendsystemdatetime desc
but if add column in select
list, index not used
select usertask_id, usertask_sequencenumber, usertask_identitat, ....., usertask_subject usertask usertask_identitat = @identitat order usertask_lastsendsystemdatetime desc
why adding column different primary key makes sql server execution plan doesn't use index on usertask_identitat
column?
following link http://bytes.com/topic/sql-server/answers/144592-sqlsever-not-using-index seems number of times filtered value repeated on column, can make index not used, have tried doing query @identitat value repeated 60.000 times , other repeated 175 times , results same, index on identitat
column ignored.
this taking me crazy!!!
thanks help.
ok - long select column that's in index, or clustering key (usually, primary key), index used, since sql server can find information needs (the usertask_identitat
column, , clustered index column(s) ) in leaf level of index navigation structure. can return data needed select
query directly index's leaf level pages.
however: if need select second column, neither in index definition, nor part of clustering key, sql server have so-called bookmark lookup actual data pages.
so for every single row finds in nonclustered index, have take clustering index value, search clustered index find actual data page @ leaf level of clustered index, , pick out 1 column want.
bookmark lookups great small numbers of hits - totally devastating performance if you're selecting thousands of rows. in case, sql server query optimizer correctly uses clustered index scan instead - since in clustered index, on leaf level, has all rows available right away.
so: if have index on usertask_identitat
, need second column usertask_sequencenumber
- include column in nonclustered index of yours:
create nonclustered index ix_usertask_identitat on dbo.usertask(usertask_identitat) include(usertask_sequencenumber)
with this, additional column present in leaf level of non-clustered index (it cannot used in where
clause - it's not part of navigation structure of index!) - , second select
can again satisfied leaf-level nodes of nonclustered index -> no expensive bookmark lookups needed -> index used again.
long story short: unless nonclustered index highly selective (e.g. returns 1% of rows or less), , unless nonclustered index covering index (an index contains columns needed satisfy particular query), changes pretty high sql server not use nonclustered index.
for more information:
Comments
Post a Comment