To restate:
- You have table PhoneStatus
- With a clustered index
- And a non-clustered index on columns PhoneStatus and PhoneId, in that order
- You are issuing an update with "...WHERE PhoneId = 126"
- There are 20 million rows in the table (i.e. it's big and then some)
SQL will take your query and try to figure out how to do the work without working over
the whole table. For your non-clustered index, the data might look like:
PhoneStatus PhoneID
A 124
A 125
A 126
B 127
C 128
C 129
C 130
etc.
The thing is, SQL will check the first column first, before it checks the value
of the second column. As the first column is not specified in the update, SQL
cannot "shortcut" through the index search tree to the relevant entries, and so will have to scan the entire table. (No, SQL is not clever enough to say "eh, I'll just check
the second column first", and yes, they're right to have done it that way.)
Since the non-clustered index won't make the query faster, it defaults to a table
scan -- and since there is a clustered index, that means it instead becomse a clustered index scan. (If the clustered index is on PhoneId, then you'd have optimal performance on your query, but I'm guessing that's not the case here.)
When you use the hint, it forces the use the non-clustered index, and that will be faster
than the full table scan if the table has a lot more columns than the index (which
essentially has only the two), because there'd be that much less data to sift through.