views:

73

answers:

5

I had previously posted a question about my query speed with an XML column. After some further investigation I have found that it is not with the XML as previously thought. The table schema and query are very simple. There are over 800K rows, everything was running smooth but not with the increase in records it is taking almost a minute to run.

The Table:

/****** Object:  Table [dbo].[Audit]    Script Date: 08/14/2009 09:49:01 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Audit](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [PID] [int] NOT NULL,
    [Page] [int] NOT NULL,
    [ObjectID] [int] NOT NULL,
[Data] [nvarchar](max) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
   [Created] [datetime] NULL,
CONSTRAINT [PK_Audit] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF,          ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

The query:

SELECT *
FROM Audit
WHERE PID = 158
AND Page = 2
AND ObjectID = 93

The query only return 26 records and the interesting thing is that if I add "TOP 26" the query executes in less than a second, if I change it to "TOP 27" then it take a minute. Even if I change the query to SELECT ID, it does not matter.

Any help is appreciated

+1  A: 

Why not add a covering index for the Page and Object ID columns and call it a day?

Nissan Fan
You forgot the PID...
Guffa
Yep, sorry :) You should index anything showing up in the where clause. I didn't list PID cause I misread it as ID, which is the Primary Key and will already have an index.
Nissan Fan
Well, it's actually possible to create a primary key without an index...
Guffa
+1  A: 

I think you must add non unique indexes to your columns you want to search. Indexing will certainly reduce the search time it takes. Whether requesting single column or multi column in SELECT query will not make any difference. The time it takes to individually compare rows needs to be reduced by indexing.

Akash Kava
+6  A: 

You have an index on ID, but your query is using other columns instead. Therefore, you're probably getting a full table scan. Changing to SELECT ID makes no difference because it's not anywhere in the WHERE clause.

It's quick when you ask for TOP 26 because it can quit once it finds 26 rows because you don't have any ORDER BY clause. Changing it to TOP 27 means that, once it finds the first 26 (which are all the matches, according to your post), it can't quit looking; it has to continue to search until it either finds a 27th matching row or reaches the end of the data.

A SHOW PLAN would have shown you the problem pretty quickly.

Ken White
That for the info on the why the TOP 27 takes longer. I did not think about that.
Dustin Laine
+2  A: 

Add an index for the PID, Page and ObjectID fields.

Guffa
A: 

the 26 rows are probably near the start of the table, when you scan you find them fast and abort the rest of the scan, when looking for the 27th that doesn't exist you scan the entire table, which is slow!

when looking for these type of problems try this from query management studio:

run: _SET SHOWPLAN_ALL ON_
then run your query, look for the word "SCAN", they is mostlikely where your query is running slow, figure out why no index is being used.

in this case you need to ad an index. I generally add an index based on how I query the data, if you always have one of the three: PID, Page, and Object ID, add an index with that column first, add another column to that index if you have that value sometimes too. etc.

KM