Question

I have a SQL query that contains a derieved table.

The derived query looks something like this:

SELECT 
   ObjectId, MIN(StatusHistoryId) AS FirstStatusHistoryId
FROM 
   dbo.StatusHistory
WHERE 
   ObjectType = 'SchemeTypeApplication' 
   AND (StatusId = 504 OR StatusId = 501) 
   AND IsDeleted = 0    
GROUP BY 
   ObjectId

This takes around 2 minutes to complete on it's own, it pulls back nearly 300k rows. The whole query (with this inside) takes around about the same. Without the derived table, it takes less than a second, so I know it's the derieved query that causing a problem.

My question is, is there anyway to improve the speed of the dereived table query? Maybe adding some indexes to the StatusHistory table (I'm a bit rubbish with indexing...)? Or some other approach other than using a derived table?

Any suggestions are appreciated.

Thanks

Was it helpful?

Solution

As JonH noted, expand an index and have the key elements based on what would be considered the smallest granularity of expected results based on you WHERE criteria... Your "ObjectType" being a string might be better optimized if it were more an an enumerable integer value basis than text too. As for granularity. Which would return the least amount of records... status ID being 501 and 504 combined (via your OR condition) vs the object type of "SchemeTypeApplication". If 501 has 50,000 records, 504 has 30,000 records, but "SchemeTypeApplication" has 475,000 records, I would have my index on the status ID first, otherwise, vice-versa... Let the index blow through 80,000 records and within that, how many of the 475,000 object types are 501 and 504, maybe 50,000 and you're done. Yes, your original comment refers to returning about 300k rows, but this is just a sample of determination of an optimizing index technique based on how your queries will commonly be used. So, I would index on something like

(statusID, ObjectType, IsDeleted, ObjectID)

OTHER TIPS

See my comment above - you could also introduce an index on the StatusID field if there isn't already one on it. Try to put your more restrictive columns in the WHERE clause in order of how many records could be returned.

If you are using Management Studio 2008 (with a 2008 or 2005 database) you can look at your execution plan to see if it recommends any missing indexes that should be created.

My guess is that it will have a recommendation for this query.

There are some screenshots here: http://weblogs.sqlteam.com/mladenp/archive/2008/12/29/SQL-Server-Management-Studio-2008-suggests-missing-indexes-with-actual.aspx

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top