Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is doing a top(1) on an indexed column in SQL Server slow?

Tags:

I'm puzzled by the following. I have a DB with around 10 million rows, and (among other indices) on 1 column (campaignid_int) is an index.

Now I have 700k rows where the campaignid is indeed 3835

For all these rows, the connectionid is the same.

I just want to find out this connectionid.

 use messaging_db;
 SELECT     TOP (1) connectionid
 FROM         outgoing_messages WITH (NOLOCK)
 WHERE     (campaignid_int = 3835)

Now this query takes approx 30 seconds to perform!

I (with my small db knowledge) would expect that it would take any of the rows, and return me that connectionid

If I test this same query for a campaign which only has 1 entry, it goes really fast. So the index works.

How would I tackle this and why does this not work?

edit:

estimated execution plan:

select (0%) - top (0%) - clustered index scan (100%)
like image 747
Toad Avatar asked Mar 16 '10 11:03

Toad


People also ask

Can an index make a query slower?

As shown, indexes can speed up some queries and slow down others.

How do I make indexes faster in SQL?

Add the index to the new empty table. copy the data from the old table to the new table in chunks. drop the old table. My theory is that it will be less expensive to index the data as it is added than to dig through the data that is already there and add the index after the fact.

What does top 1 do in SQL?

The TOP 1 means to only return one record as the result set. which record is returned, depends on the column that is specified in the order by clause. If you want to find the record with the minimum value for a particular column, you would query the record with the ORDER BY being ascending (ASC).

How does SQL Server top 1 work?

Limits the rows returned in a query result set to a specified number of rows or percentage of rows in SQL Server. When you use TOP with the ORDER BY clause, the result set is limited to the first N number of ordered rows. Otherwise, TOP returns the first N number of rows in an undefined order.


2 Answers

Due to the statistics, you should explicitly ask the optimizer to use the index you've created instead of the clustered one.

SELECT  TOP (1) connectionid
FROM    outgoing_messages WITH (NOLOCK, index(idx_connectionid))
WHERE  (campaignid_int = 3835)

I hope it will solve the issue.

Regards, Enrique

like image 159
enrique Avatar answered Sep 27 '22 17:09

enrique


I recently had the same issue and it's really quite simple to solve (at least in some cases).

If you add an ORDER BY-clause on any or some of the columns that's indexed it should be solved. That solved it for me at least.

like image 22
cnyborg Avatar answered Sep 27 '22 16:09

cnyborg