views:

1152

answers:

7

I have a query that I'm executing from a .NET application to a SQL Server database and it seems to take quite a while to complete (5+ Minutes). I created a test app in c# to try to see what was talking so long (the query should return quickly).

As I was reconstructing the query by adding in elements to see which portion was taking so long, I ended up reconstructing the query practically verbatim where the only difference was the spaces in the original query and a capitalization difference. This difference returned a result in about 100 milliseconds.

Has anybody seen this before? I'm wondering if there are services turned off in our server (since a coworker has the same problem) or on our computers.

Thanks in advance for any help with this.

Code Sample Below (The Difference in in the first line of the query at the end (fk_source vs. fk _Source):

//Original
    OleDbCommand comm = new OleDbCommand("select min(ctc.serial_no) as MIN_INTERVAL from countstypecode ctc, source s, countstype ct, counts c where ct.value_id=c.value_id and s.c_id=ct.fk_source and " +
      "ct.timeinterval=ctc.typename and ct.timeinterval in ('15min','1h','1day') and c.time_stamp >=  CONVERT(datetime,'01-01-2008',105)  and c.time_stamp < " +
      "CONVERT(datetime,'01-01-2009',105)  and s.c_id = '27038dbb19ed93db011a315297df3b7a'", dbConn);

//Rebuilt
    OleDbCommand comm = new OleDbCommand("select min(ctc.serial_no) as MIN_INTERVAL from countstypecode ctc, source s, countstype ct, counts c where ct.value_id=c.value_id and s.c_id=ct.fk_Source and " +
      "ct.timeinterval=ctc.typename and ct.timeinterval in ('15min','1h','1day') and c.time_stamp >= CONVERT(datetime,'01-01-2008',105) and c.time_stamp < " +
      "CONVERT(datetime,'01-01-2009',105) and s.c_id='27038dbb19ed93db011a315297df3b7a'", dbConn);
+1  A: 

Since you are using SQL Server 2005, have you tried with a SqlCommand object instead of the OleDbCommand object?

Russ Cam
If you're using SQL Server _AND_ .Net, this just makes sense.
Joel Coehoorn
Yes, but its meant to be interchangeable with other databases, we just noticed this behaviour in SQL server, so I asked about it specifically.
Fry
+1  A: 

I'm not seeing a difference in your queries which would affect performance - what about caching or index/statistics changes between runs? The execution plan may have changed due to statistics or index changes.

Regarding the case: Case can matter if the database is set to be case-sensistive, but for both queries to run in a case-sensitive database, there would have to be columns named in both formats - the query parser will obey the case - it won't cause a performance difference.

Cade Roux
A: 

firstly, are you 100% sure its the query that is going wrong? Check the trace profile in sql server to see how long its taking in the DB.

Secondly, are you getting the same number of results back. The capitalisation should not matter by default in sql server, but it could have been set up differently.

gbjbaanb
A: 

If I had a query that took "5+ minutes", I wouldn't be worried about the 100 milliseconds it takes to match up the case of the string.

Joel Coehoorn
The difference in the 2 queries, 1 returned in 5+ minutes, 1 returned in 100 ms
Fry
A: 

Hi, thanks for all your answers, I'll respond to each in turn:

1) Russ, I agree that SQLConnection would be better, but unfortunately I do not get to set the type of connection. I just created a small app to test this query, but the query is dynamically created in a much larger application.

2) gbjbaanb, It's not a server issue I think, because I can run both queries from the management studio in about the same time, it only seems to be a problem when run through oledb in .net (1.1 and 2.0). We've run a profiler on it and the trace file confirmed that it took over 5 minutes to complete the query when called this way.

3)Joel Coehoorn, Agreed, but really what I'm trying to get at here is "why" because right now we don't know how big this problem is and where it lies.

4)Cade Roux, The difference is very reproduceable, so I don't think it's an issue with index changes or caching since I have run the tests back to back with the same results and that they take about the same time in SQL Server to run.

Fry
You've isolated to between just those two queries (no other factors) and get that performance difference every time?I'd open a ticket with Microsoft - there's not enough difference between those queries to merit that performance difference.
Cade Roux
+3  A: 

I suspect that this is a procedure cache issue. One benefit of stored procedures is that the plan is stored for you, which speeds things up. Unfortunately, it's possible to get a bad plan in the cache (even when using dynamic queries).

Just for fun, I checked my procedure cache, ran an adhoc query, checked again, then I ran the same query with different capitlization and I was surprised to see the procedure count higher.

Try this....

Connect to SQL Server Management Studio.

DBCC MemoryStatus

Select Columns... From TABLES.... Where....

dbcc MemoryStatus

Select Columns... From tables.... Where....

dbcc MemoryStatus

I think you'll find that the TotalProcs changes when the statement changes (even when the only change is case sensitive).

Updating your statistics may help. That is a rather slow running process, so you may want to run that during a slow period.

G Mastros
A: 

Thanks to G Mastros for the most complete answer, although in retrospect the update in statistics was suggested by Cade. G Mastos' solution was better suited to my level of SQL Server experience, however.

Thanks for helping everybody!

I'm going to look into why this seemingly innocent difference has such large consequences

Fry