How a query uses an index

  • I have a table with what I would consider way too many indexes on it (35 - and the table isn't particularly wide ). So I am looking to remove the redundant indexes which have no reads against them. Some of the indexes appear to very similar for example the two described below:

    Ix_Covering30

    Index Key columns: CreatedDate, Status

    Included columns: UserID, CallerName, UserBA, LookupID

    and then very similar to the one above :

    Ix_Covering29

    Index Key Columns: CaseCurrentID, CreatedDate, Status

    Included columns: UserID, CallerName, UserBA

    So if I where to remove Ix_Covering30 and add the LookUpID into the included column of Ix_Covering29 would the queries that where using Ix_Covering30 now use Ix_Covering29 as it still is indexed on CreatedDate and Status but with the addition of CaseCurrentID in the index key column ?

  • Probably not. You'll note that the leading edge of the key, the first column, is different between the two indexes. That's one of the bigger driving factors for index selection since it's the column used to create the histogram in the statistics. While the index is still covering if you do what you suggested, the change to the keys suggests that you may lose some functionality. But, testing will tell you more than speculation.

    "The credit belongs to the man who is actually in the arena, whose face is marred by dust and sweat and blood"
    - Theodore Roosevelt

    Author of:
    SQL Server Execution Plans
    SQL Server Query Performance Tuning

  • thanks Grant 🙂

    The bit about the leading edge of the index always confused me, but I think you've just cleared that up !

  • Not a problem. Happy to pitch in.

    "The credit belongs to the man who is actually in the arena, whose face is marred by dust and sweat and blood"
    - Theodore Roosevelt

    Author of:
    SQL Server Execution Plans
    SQL Server Query Performance Tuning

  • SQL actually keeps track of how often an index gets used, and that info is accessible via the dm_db_index_usage_stats DMV.

    Take a look here: https://www.simple-talk.com/blogs/2012/08/08/a-quick-look-at-dm_db_index_usage_stats/

  • Rather than adding the column to the '"leading edge" you might want to consider adding it to the end of the index...this may help with the overall selectivity of the index.

    idx_NewCovering

    Index Key columns: CreatedDate, Status, CaseCurrentID

    Included columns: UserID, CallerName, UserBA, LookupID

    If the queries that typically use the index follow the same order (like below)

    WHERE CreatedDate = @Date AND Status = @status

    And then you add a new condition:

    WHERE CreatedDate = @Date AND Status = @status AND CaseCurrentID = @CCID

    It should pick up and use the same index, without a loss in functionality

    Of course, as the general rule of thumb goes "It depends", so test accordingly.

    ______________________________________________________________________________Never argue with an idiot; Theyll drag you down to their level and beat you with experience

  • MyDoggieJessie (4/3/2014)


    Rather than adding the column to the '"leading edge" you might want to consider adding it to the end of the index...this may help with the overall selectivity of the index.

    idx_NewCovering

    Index Key columns: CreatedDate, Status, CaseCurrentID

    Included columns: UserID, CallerName, UserBA, LookupID

    If the queries that typically use the index follow the same order (like below)

    WHERE CreatedDate = @Date AND Status = @status

    And then you add a new condition:

    WHERE CreatedDate = @Date AND Status = @status AND CaseCurrentID = @CCID

    It should pick up and use the same index, without a loss in functionality

    How would you add an extra predicate to a query without changing the behaviour?

    An index on CaseCurrentID, CreatedDate, Status and an index on CreatedDate, Status, CaseCurrentID are two different indexes which can support different queries. They're not equivalent

    The first one supports any where clauses of the forms:

    WHERE CaseCurrentID = @1

    WHERE CaseCurrentID > @1

    WHERE CaseCurrentID = @1 AND CreatedDate = @2

    WHERE CaseCurrentID = @1 AND CreatedDate > @2

    WHERE CaseCurrentID = @1 AND CreatedDate = @2 AND Status = @3

    WHERE CaseCurrentID = @1 AND CreatedDate = @2 AND Status > @3

    The second supports where clauses of the forms

    WHERE CreatedDate = @1

    WHERE CreatedDate > @1

    WHERE CreatedDate = @1 AND Status = @2

    WHERE CreatedDate = @1 AND Status > @2

    WHERE CreatedDate = @1 AND Status = @2 AND CaseCurrentID = @3

    WHERE CreatedDate = @1 AND Status = @2 AND CaseCurrentID > @3

    Gail Shaw
    Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
    SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability

    We walk in the dark places no others will enter
    We stand on the bridge and no one may pass

Viewing 7 posts - 1 through 6 (of 6 total)

You must be logged in to reply to this topic. Login to reply