Answered by:
SP slow from app fast from SSMS. Also plan guides for entire SP?

Question
-
OK, I see this is a perennial, but now it's hitting me!
It's a winapp, in C#, using connection pooling.
sys.dm_exec_sessions does not show any different settings, and what settings would matter anyway.
There is no blocking going on.
It's SQL Server 2008 R2 Standard on Windows Server 2008 R2 Standard, both 64 bit.
I run profiler and get the textdata from the slow run from the app, paste it into SSMS, and it runs fast against the same server, so it does not seem to be a matter of parameter sniffing.
It is not a matter of buffers, afaik, I can run the query fast from SSMS, then some random time later slow from the app.
The number of logical reads goes up by a factor of 1000 for the bad plan.
I can *see* the bad plan and the good plan, and they are unfortunately complex but I can quickly see in one place the good one uses merge joins instead of several layers of loops - but the question is, WHY ANY DIFFERENCES AT ALL given the same parameters? It is possible that some of the tables and statistics have changed *slightly* between runs, but nothing that should affect the plans, it's a fairly stable database.
Finally, plan guides - can I freeze an entire complex SP with one guide? All the examples seem to suggest that a guide only works for a statement or batch at a time. I guess I can feed it the entire SP as text?
Thanks,
Josh
- Edited by JRStern Friday, March 1, 2013 7:55 PM
- Moved by Tom Phillips Tuesday, April 9, 2013 3:16 PM Probably better query tuning question
Friday, March 1, 2013 7:53 PM
Answers
-
Compare the SET options between SSMS and your application. Ensure that SET options are not changed. Plan guide should be your last option. follow
http://mssqlwiki.com/tag/tuning-sql-server-query/
Thank you,
Karthick P.K |My blogs|My Scribbles|Twitter|My Facebook Group|
Please click the Mark as answer button and vote as helpful if this reply solves your problem
- Proposed as answer by Naomi N Tuesday, April 9, 2013 3:45 PM
- Marked as answer by Kalman Toth Thursday, April 18, 2013 4:26 PM
Saturday, March 2, 2013 3:19 AM
All replies
-
Compare the SET options between SSMS and your application. Ensure that SET options are not changed. Plan guide should be your last option. follow
http://mssqlwiki.com/tag/tuning-sql-server-query/
Thank you,
Karthick P.K |My blogs|My Scribbles|Twitter|My Facebook Group|
Please click the Mark as answer button and vote as helpful if this reply solves your problem
- Proposed as answer by Naomi N Tuesday, April 9, 2013 3:45 PM
- Marked as answer by Kalman Toth Thursday, April 18, 2013 4:26 PM
Saturday, March 2, 2013 3:19 AM -
What is the index REBUILD schedule? UPDATE STATISTICS? Missing indexes?
Optimization step-by-step:
http://www.sqlusa.com/articles/query-optimization/
For quick assistance, can you post code & DDL? Thanks.
Kalman Toth Database & OLAP Architect
Paperback / Kindle: Pass SQL Exam 70-461 & Job Interview: Programming SQL Server 2012Thursday, March 7, 2013 8:27 PM -
It is possible to do plan guides for stored procedures using the OBJECT plan guide type but your guides are done per statement. There is a simple example adapted from BOL below which shows this technique.
However a better solution might be to work out exactly why this is occuring. It may be as you say, subtle differences in statistics causing this. You could diagnose this with the Actual Execution Plans for the two procs and compare the estimated versus actual rowcounts. Plan cache pressure, forced cache flush, service restart etc could also cause this. It may be worth applying a JOIN hint eg OPTION ( MERGE JOIN ) as a diagnostic measure. I wouldn't necessarily recommend leaving the hint there permanently but it could help you get to the bottom of your issue.
If I was to guess, I would bet complexity is the cause, ie the optimizer makes different decisions on the same query even for the same parameters because the main query is complex. You can work round this by simplyfiying your query, eg materializing some of your data to a temp table for example or restructuring your query.
If you do decide to go down the plan guide route, here is a simple example for a multi-statement proc:
USE AdventureWorks2012 GO DBCC FREEPROCCACHE DBCC DROPCLEANBUFFERS GO CREATE PROCEDURE Sales.GetSalesOrderByCountry (@Country nvarchar(60)) AS BEGIN SELECT * FROM Sales.SalesOrderHeader h, Sales.Customer c, Sales.SalesTerritory t WHERE h.CustomerID = c.CustomerID AND c.TerritoryID = t.TerritoryID AND CountryRegionCode = @Country -- Do something else SELECT DISTINCT Name FROM Sales.SalesTerritory WHERE CountryRegionCode = @Country RETURN END GO EXEC sp_create_plan_guide @name = N'Guide1', @stmt = N'SELECT * FROM Sales.SalesOrderHeader h, Sales.Customer c, Sales.SalesTerritory t WHERE h.CustomerID = c.CustomerID AND c.TerritoryID = t.TerritoryID AND CountryRegionCode = @Country', @type = N'OBJECT', @module_or_batch = N'Sales.GetSalesOrderByCountry', @params = NULL, @hints = N'OPTION (OPTIMIZE FOR (@Country = N''US''))' GO EXEC sp_create_plan_guide @name = N'Guide2', @stmt = N'SELECT DISTINCT Name FROM Sales.SalesTerritory WHERE CountryRegionCode = @Country', @type = N'OBJECT', @module_or_batch = N'Sales.GetSalesOrderByCountry', @params = NULL, @hints = N'OPTION (MAXDOP 1)' GO EXEC Sales.GetSalesOrderByCountry 'AU' WITH RECOMPILE GO EXEC Sales.GetSalesOrderByCountry 'US' WITH RECOMPILE GO EXEC sp_control_plan_guide 'DROP', 'Guide1' EXEC sp_control_plan_guide 'DROP', 'Guide2' GO
Can you post a simple repro of your issue?
- Edited by wBob Friday, March 8, 2013 3:40 PM
Friday, March 8, 2013 3:36 PM -
It is possible to do plan guides for stored procedures using the OBJECT plan guide type but your guides are done per statement.
...
Can you post a simple repro of your issue?
Ugh. Type "object" can't handle a batch of multiple statements? Disappointing. I know this feature has only been around since SQL 2005 but I've never had to resort to it before.
Unfortunately the SPs I have to deal with are large and complex, even though the data is a modest (by modern standards) 20gb. Some of the individual select statements are heroic in size and complexity. I guess they are still a single statement, but the SPs typically have a dozen or more of these, and I hate tracking down the issues one statement at a time.
The other option of doing a total rewrite so I can hand-optimize is hardly practical either, we'd be talking weeks or months per SP including QA, and what is more, I'm finding that SQL Server can be quite clever at doing intra-statement optimizations that are hard or impossible to specify at the TSQL level even with options and hints.
--
I only wish I could do simple repros on these kinds of issues, but if I were wishing, I'd wish for the problems to just go away. In this app they put a fair amount of business logic (I guess we can call it) into the SPs. A lot of stuff could probably be simplified with a total rearchitecture of the data model, but like a lot of projects they didn't necessarily know where they were going when they started, and things kind of piled in, and are not always cleanly normalized in the data model, and anyway a lot of the complexity is in the business process itself and has to go somewhere!
I just seem to be running foul of a lot of basic SQL Server functions on this app, for no reason I can pin down, yet. I think a factor is the "lumpyness" of the data, you can have zero, one or two, or hundreds of entries per key value, and the optimal plans for the different cases are violently different. We're also in a VM environment and limited to just four cores and maxdop=1, where in different environments over the past few years I've generally had dozens of cores to work with which can brute force their way through a lot of problems.
(I've already gotten them to triple the RAM here, but to go from four cores to 16 or more would require exiting the VM world, much less more expensive licenses).
So I seem to find myself fighting with SQL Server's normally helpful automagic optimization functions, and noticing a lot of stuff that in most environments nobody would ever pay attention to.
FWIW,
Josh
Friday, March 8, 2013 5:21 PM -
-
What you are describing is almost certainly due to "parameter sniffing". Please see: http://www.sqlusa.com/bestpractices/parameter-sniffing/
Tuesday, April 9, 2013 3:15 PM