all groups > sql server programming > september 2006 >
You're in the

sql server programming

group:

Is is normal behaviour to see a table scan for this query?



Is is normal behaviour to see a table scan for this query? mchi55 NO[at]SPAM hotmail.com
9/21/2006 11:34:33 PM
sql server programming: I have a table with 220000 rows.

There is a column called status_id. I have a nonclustered index on
statusid.

if I do a

select from table
where status_id = 161

I get a table scan with the non clusteredindex.
There are about 16000 records with a status_id of 161. This there no
way to avoid the table scan since there are so many records? Why is
it not using the index?
select *
where status_id = 161 also takes like 2 minutes to run.

If I place a clustered index on status_id...the query returns in a
split second and uses a clustered index seek.
For production purposes...I can't place the clustered index on
status_id.

What can I do?

Also...the table has about 200 rows...completely unnormalized and a
mess.
Re: Is is normal behaviour to see a table scan for this query? mchi55 NO[at]SPAM hotmail.com
9/21/2006 11:37:25 PM

actually...to edit the above message...the query does NOT return in a
split second with the clustered index. It still takes a while.

But the table scan does go away.



[quoted text, click to view]
Re: Is is normal behaviour to see a table scan for this query? Tibor Karaszi
9/22/2006 12:00:00 AM
Think about it. You return 16,000 rows out of 220,000. If SQL Server were to use the NC index, it
would seek through the index for the first hit, and then *for every row* access the page where the
data resides. I.e., it will do 16,000 page accesses, plus the index page accesses. It is probably
cheaper to just scan the table. Try forcing the NC index though an index hint and compare I/O, for
instance.

Never ever do SELECT * in production code (except for EXISTS, where the * don't mean "all the
columns"). This is because you virtually lose one very important tuning option: to cover the query
with an NC index. Include all the column needed by that query, and the index will most probably be
used as the index covers the query an no data-page accesses are needed.

--
Tibor Karaszi, SQL Server MVP
http://www.karaszi.com/sqlserver/default.asp
http://www.solidqualitylearning.com/


[quoted text, click to view]
Re: Is is normal behaviour to see a table scan for this query? Tracy McKibben
9/22/2006 7:50:59 AM
[quoted text, click to view]

It's because you're using SELECT *. You're telling the query to return
every field for the matching rows. Let's look at a different variation
of your query:

SELECT status_id, someothercolumn
FROM table
WHERE status_id = 161

If you look at the execution plan for this query, you'll see that it
(probably) does an index seek using your nonclustered index, followed by
a bookmark lookup. It uses the index to locate records matching the
status_id filter, but because the index doesn't include the
"someothercolumn" column, it has to go to the table (using a bookmark
lookup) to get that value.

Now, back to your example:

SELECT *
FROM table
WHERE status_id = 161

You've just asked it to return EVERY column for every row matching your
filter condition. Because the index doesn't include EVERY column, a
large bookmark lookup will have to be done to get all of those values.
The query engine has determined that it is "cheaper" to just scan the
table and grab everything in one pass, rather than use the index, then
make a seperate trip to the table to get the other values.

With a clustered index, the index *IS* the table, so there's no need to
make a return trip to do a bookmark lookup.

Does that help?


--
Tracy McKibben
MCDBA
AddThis Social Bookmark Button