So basically I have this relatively long stored procedure. The basic execution flow is that it SELECTS INTO
some data into temp tables declared with he #
sign and then runs a cursor through these tables a generate a 'running total' into a third temp table which is created using CREATE
. Then this resulting temp table is joined with other tables in the DB to generated the result after some grouping etc. The problem is that this SP had been running fine until now returning results in 1-2 minutes. And now suddenly its taking 12-15 minutes. If I extract the query from the SP and executed it in the management studio by manually setting the same parameters it returns results in 1-2 minutes but the SP takes very long. Any idea what could be happening. I tried to generate the Actual Execution plans of both the Query and the SP but it couldn't generate it because of the cursor. Any idea why the SP takes so long while the query doesn't?
views:
394answers:
8I would suggest the issue is related to the type of temp table (the # prefix). This temp table holds the data for that database session. When you run it through your app the temp table is deleted and recreated.
You might find when running in SSMS it keeps the session data and updates the table instead of creating it.
Hope that helps :)
I would guess it could possible be down to caching. If you run the stored procedure twice is it faster the second time?
To investigate further you could run them both from management studio the stored procedure and the query version with the show query plan option turned on in management studio, then compare what area is taking longer in the stored procedure then when run as a query.
Alternativly you could post the stored procedure here for people to suggest optimizations.
Try recompiling the sproc to ditch any stored query plan
exec sp_recompile 'YourSproc'
Then run your sproc taking care to use sensible paramters.
Also compare the actual execution plans between the two methods of executing the query.
It might also be worth recomputing any statistics.
For a start it doesn't sound like the SQL is going to perform too well anyway based on the use of a number of temp tables (could be held in memory, or persisted to tempdb - whatever SQL Server decides is best), and the use of cursors.
My suggestion would be to see if you can rewrite the sproc as a set-based query instead of a cursor-approach which will give better performance and be a lot easier to tune and optimise. Obviously I don't know exactly what your sproc does, to give an indication as to how easy/viable this is for you.
As to why the SP is taking longer than the query - difficult to say. Is there the same load on the system when you try each approach? If you run the query itself when there's a light load, it will be better than when you run the SP during a heavy load.
Also, to ensure the query truly is quicker than the SP, you need to rule out data/execution plan caching which makes a query faster for subsequent runs. You can clear the cache out using:
DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS
But only do this on a dev/test db server, not on production. Then run the query, record the stats (e.g. from profiler). Clear the cache again. Run the SP and compare stats.
Hi ,
1) When you run the query for the first time it may take more time and one more point is that if you are using any corellated sub query and if you are hardcoding the values it will be executed for only one time and when you are not hardcoding it and run it through the procedure and if you are trying to derive the value from the input value then it might take more time.
2) In rare cases it can be due to network trafic also where we will not have consistancy in the query execution time for the same input data
I'd also look into parameter sniffing. Could be the proc needs to handle the parameters slighlty differently.
This is the footprint of parameter-sniffing. See here for another discussion about it; http://stackoverflow.com/questions/1007397/sql-poor-stored-procedure-execution-plan-performance-parameter-sniffing
There are several possible fixes, including adding WITH RECOMPILE to your stored procedure which works about half the time.
The recommended fix for most situations (though it depends on the structure of your query and sproc) is to NOT use your parameters directly in your queries, but rather store them into local variables and then use those variables in your queries.
I usually start troubleshooting issues like that by using "print getdate() + ' - step '". This helps me narrow down what's taking the most time. You can compare from where you run it from query analyzer and narrow down where the problem is at.