Why isn't SQL Server using my index?

后端 未结 3 952
感情败类
感情败类 2020-12-29 03:45

In our database we have this table with 200.000 rows

CREATE TABLE dbo.UserTask (
    UserTask_ID int NOT NULL IDENTITY (1, 1),
    UserTask_SequenceNumber in         


        
相关标签:
3条回答
  • 2020-12-29 04:20

    OK - as long as you select only the column that's in the index, or something from the clustering key (usually, this is the primary key), then the index will be used, since SQL Server can find all the information it needs (the UserTask_IDEntitat column, and the clustered index column(s) ) in the leaf level of the index navigation structure. So it can return the data needed for that SELECT query directly from the index's leaf level pages.

    However: if you need to select a second column, that is neither in the index definition, nor part of the clustering key, then SQL Server would have to do a so-called bookmark lookup into the actual data pages.

    So for every single row it finds in your nonclustered index, it would have to take the clustering index value, search the clustered index to find the actual data page at the leaf level of that clustered index, and then pick out that one column that you want.

    Bookmark lookups are great for small numbers of hits - they are totally devastating for performance if you're selecting thousands of rows. In that case, the SQL Server query optimizer correctly uses a clustered index scan instead - since in the clustered index, on the leaf level, it has all the rows available right away.

    So: if you have an index on UserTask_IDEntitat and you sometimes need a second column UserTask_SequenceNumber too - then you could include that column in that nonclustered index of yours:

    CREATE NONCLUSTERED INDEX IX_UserTask_IDEntitat 
    ON dbo.UserTask(UserTask_IDEntitat)
    INCLUDE(UserTask_SequenceNumber)
    

    With this, that additional column is present in the leaf level of that non-clustered index only (it cannot be used in a WHERE clause - it's not part of the navigation structure of the index!) - and your second SELECT can again be satisfied from the leaf-level nodes of the nonclustered index -> no expensive bookmark lookups are needed -> your index will be used again.

    Long story short: unless your nonclustered index is highly selective (e.g. returns 1% of your rows or less), and unless your nonclustered index is a covering index (an index that contains all the columns needed to satisfy a particular query), then changes are pretty high that SQL Server will NOT use your nonclustered index.

    For more information:

    • SQL Server Indexing Basics
    • SQL Server – Learning SQL Server Performance: Indexing Basics – Video
    0 讨论(0)
  • 2020-12-29 04:31

    I faced with situation when the same query makes different plan on different databases. On the one DB it use non-clustered index and on the other - table scan.

    Also this index doesn't have all field in INCLUDE, and the best solution here would be to add all necessary selected fields to index INCLUDE. In my case drop free cache helps though.

    DBCC freeproccache

    Sometimes query plan builder ignores index if it has fragmentation more 50%, because it spend more time to find row in index than to scan the entire table.

    0 讨论(0)
  • 2020-12-29 04:39

    You can use the query hints in the query to make use of Index. Following is a link for further details: http://msdn.microsoft.com/en-us/library/ms181714.aspx

    0 讨论(0)
提交回复
热议问题