views:

275

answers:

3

In code that I inherited, I have a SqlDataSource that has a fairly complex select statement that for certain SelectParameters, always times out ("Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.").

When I run the exact same query with the same parameters in management studio, the query never times out and always takes less than a second.

Does anyone have an idea what the problem could be here? I can't make sense of it.

+1  A: 

could be locking/blocking, if people are doing work in the database your select may wait until their transaction is complete. The timeout would be hit or miss, depending on the other transactions in the database.

in management studio, run SET SHOWPLAN_ALL ON, and then run your query. Look for "SCAN" in the output. If you have a table or index scan you are more likely to be a victim of locking/block, since you must process the entire index/table and anyone locking a row in there will force you to wait.

when you run the application, and screen is not refreshing fast run this in management studio:

EXEC sp_lock

it will give you some basic info an any locking currently going on.

KM
Wouldn't the locking occur whether I'm in Management Studio or not? I ran the query a bunch of times in Management Studio; it never times out. With SqlDataSource, it always does. Or is there maybe some setting that forces SqlDataSource to always wait for locks while Mangement Studio simply doesn't?
Stefan
@Stefan, edit your question to say _it always times out when run from SqlDataSource, but never from management studio_, this is an important clue.
KM
Ok, done. Thanks!
Stefan
+1  A: 

Just a shot in the dark: The parameters are not actually the same. In SSMS you pass in ASCII parameters for the query, while in ADO.Net you pass Unicode ones. SqlCommand.Parameters.AddWithValue("@myParam", myValue) will add a parameter of type NVARCHAR when myValue is a String. Due to te conversion rules in SQL if you have SELECT ... FROM ... WHERE myField = @myParam and myField is Ascii (VARCHAR) and @myParam is Unicode (NVARCHAR) then the execution must do a table scan, cannot use an index on myField, resulting in awfull performance when compared to SSMS execution.

As I said, this is just a shot in the dark, but is a common pitfall and fairly subtle to debug.

Remus Rusanu
I like shots in the dark, and that was a pretty convincing one.I did set the DbType/Type of the SelectParameters on the SqlDataSource and that didn't help. Also, note that the SqlDataSource doesn't always time out; just for certain parameters. For those, it times out consistently while Management Studio doesn't.
Stefan
If you are 1000% convinced (no, that extra 0 is not a typo) that the queries are identical in SSMS and ADO.Net, you should compare the execution plans (the Profiler can show you the graphical execution plan of the ADO.Net statement, capture the Plan XML event). If the plans are different (so is not some ADO.Net client misbehave) then you one possible place to look is at the SET options. Look at sys.dm_exec_sessions for ADO.Net connection and SSMS connection and compare them, see what si different then check MSDN for the implication of the different SETs
Remus Rusanu
Yep, they were identical (copied it over from SQL Profiler).And you were right... it was the set-options. I changed "transaction isolation level" and it doesn't time out any more. I wish I could mark both yours and KM's as the answer because he was on the right track too. But ultimately, your last comment really helped me solve this one, so answer to you. Thanks!
Stefan
A: 

Try following, maybe this will clarify what's going on:

  1. In sql profiler, capture exact statement into which your complex SQL statement translates and run it in Viual Studio.

  2. When the sql statement in question is running, go check activity monitor in management studio. It could give you an idea, what might be blocking the sql.

  3. It's important to see what else is running at the same time. Is application multi-threaded? Is sql connection getting closed/disposed immediately after use (if not, it may not get closed timely)? Is same sql connection used by multiple threads?

galets