Here is the problem I am having. A table that I am querying has 170 million rows. I wrote a stored procedure to do a simple query about the latest entries into the table. When I write the WHERE clause with a hard-coded string like this:
SELECT top 500 a.field1 , a.field2, a.field3
FROM database..hugeTable a( nolock )
WHERE a.StartTime > '2012-07-17 10:10:35.477'
it is very fast. Less than a second. StartTime is in a non-clustered index.
However, what I really want is this:
DECLARE @fifteenMinutesAgo datetime;
SET @fifteenMinutesAgo = DATEADD(n , -15 , GETDATE());
SELECT top 500 a.field1 , a.field2, a.field3
FROM database..hugeTable a( nolock )
WHERE a.StartTime > @fifteenMinutesAgo
The problem is that when I run the second query, it takes almost 3 minutes!
So I started messing around and searching like crazy. I thought that it might be a datatype problem so I tried various CASTs and CONVERTs and had no success. I tried using OPTIMIZE FOR but realized it would not work on this version of SQL. I checked the datatype of StartTime; it is of type datetime.
Another thing that I tried, which was very weird, was this:
DECLARE @fifteenDaysAgo datetime;
SET @fifteenDaysAgo = DATEADD(d , -15 , GETDATE());
SELECT top 500 a.field1 , a.field2, a.field3
FROM database..hugeTable a( nolock )
WHERE a.StartTime > @fifteenDaysAgo
I changed it from searching for the last 15 minutes, to the last 15 days. Magically it was super-fast again! Less than a second.
This lead me to believe that somehow it is hard for SQL to compare time? It didn’t need to look at the TIME portion of the datetime to see if it fit the compare statement? I don’t know. Here I am grasping at straws.
So my question is, how can I make this reasonably fast and still keep my @fifteenMinutesAgo dynamic?
It looks like you have “parameter sniffing” problem with your procedure.
WITH RECOMPILEoption should help