|
Hi all I have an app that runs a advanced search query as below I've tuned this search query and it is as optimised as possible. I have looked to see what the app is running and it is literally this stored proc with various parameters. I have run the proc with same parameters in SSMS and it is blazing quick sub second. However when the app is running it, it is really slow or hangs. How do i rule out that it is the database that is the issue? i'm not very familiar with the various diagnostic DMVs in SQL or understand if what i'm looking at is high etc. so could someone help me and i'll post stats etc.? Thanks! I have run which i found which gives me
(comments are locked)
|
|
I would take a punt that you've bad plans, caused by parameter sniffing. One 'cure' as well as option(recompile) is to set the parameters to local variables, and then use them in the script instead. I don't know what you mean by parameter sniffing and what do you mean by local variables? :) There is a search screen in the application which is passing variables to the stored procedure.
Jul 12 '12 at 02:18 PM
jhowe
Ah sorry! http://www.simple-talk.com/sql/t-sql-programming/parameter-sniffing/ Option 2 talks about using local variables - if you're still stuck I can mock up your proc....
Jul 12 '12 at 02:22 PM
Kev Riley ♦♦
+1. I would prefer OPTION(Recompile) as the caveat with local variables being the engine starts with a plan that there would be 30 percent data related to the local variable. But as always testing should give the final word. BTW, this was the same I thought of to letting jhowe know, but after he would have digested the multiple execution plans ;)
Jul 12 '12 at 02:42 PM
Usman Butt
I've used sp_recompile on the customer table which seems to have resolved the issue. How do i stop SQL from using a bad query plan in the future?
Jul 12 '12 at 04:51 PM
jhowe
(comments are locked)
|
|
BTW, what is the output of the following I guess there could be two plans for the same procedure. sorry didn't realise i had it on master
Jul 12 '12 at 12:15 PM
jhowe
As I guessed there are two plans because of the different settings. Please make sure that your application have the same settings as your SSMS have. The settings like ANSI_NULL_DFLT_ON, ANSI_NULLS,ANSI_PADDING, ANSI_WARNINGS,ARITHABORT etc
Jul 12 '12 at 12:33 PM
Usman Butt
What options would make a difference performance wise, and how can i see what options i have set or what options the app server is using?
Jul 12 '12 at 02:05 PM
jhowe
This can make a big difference as the plan could not be efficient. You can run SQL Profiler to see the settings made by the application as well as SSMS. For SSMS, you can also see these settings through Tools-> Options -> Query Execution -> Advanced/ANSI
Jul 12 '12 at 02:17 PM
Usman Butt
(comments are locked)
|
|
@jhowe - It seems that you are experiencing what @Kev Riley has correctly identified as parameter sniffing. SQL server has decided on a plan for the first time the sproc was called and this is optimal only for searches with very similar / identical values as the first call. When you issued sp_recompile the plan that was in cache was kicked out and the next call of the procedure was then compiled and ran really fast. I would bet that a subsequent call with completely different parameter values would result in really slow execution. The idea that @Usmann Butt offered up: Another alternative to If you have any more questions, let us know. Wow, that turned out a little longer than I expected!
Jul 13 '12 at 06:50 AM
WilliamD
@WilliamD +1 but I do not think the content makes you bore while reading ;) I totally agree that OPTIMIZE FOR works better in most cases. But I do not think that OPTIMIZE FOR would be as beneficial as it should be in this case. Reason being it is a dynamic search. The parameters may be supplied a value OR may not be. So I would still fell that OPTION(RECOMPILE) has more probability of getting a better execution plan (Unless Recompile cost proves be too much). As always testing would yield the final results. Moreover, Although I hate dynamic sql, but seems like a more viable solution than any other. @jhowe An excellent article by Erland Sommarskog on such dynamic search is here. You would find very fruitful information and could optimize your search more.
Jul 13 '12 at 08:07 AM
Usman Butt
Thanks everyone for looking at this. I'm definitely suffering from parameter sniffing. I just tested again this morning through SSMS one query takes under a second, through the app it takes 30 + seconds. Let me describe the environment, it's a smallish db about 6gb. However we are running what is effectively a small call centre with the agents using the advanced search on a regular basis. My worry is that with the agents supplying random parameters i will run into trouble again. The server is an 8 core CPU with 8GB ram. It is very underutilised. I think the server could easily take compiling this stored proc on the fly. The maximum amount of times this procedure would be run in a min. is prob 5-10 times. My options are OPTIMIZE FOR VS OPTION RECOMPILE VS LOCAL PARAMETERS. The problem is I don't have the data in a test environment for security reasons, i can't replicate this in a test environment and test it the decision i make has to be made on the LIVE environment. Opinions? @WilliamD how can i use optimize for? I can't supply parameters as it's dynamic they will change all the time... I'm leaning towards option recompile at the moment... @Usman that was a great article!
Jul 13 '12 at 08:34 AM
jhowe
@jhowe I guess the article link was posted by me ;) Now back to the point. you are having more than one problems and you need to take care of all.
It happens that sometimes you do not have access to the real data, but that does not mean you should not do any testing. Make a test bud with a test data. Do your testing with different, small/huge data etc. Only, then you would know what could be the best solution.
Jul 13 '12 at 09:23 AM
Usman Butt
@jhowe - With optimize for you would look at your data spread and what the most common searches are and hopefully find a set of values that make a nice plan. Note that this method would push towards an average execution but a more consistent one. As you are only calling 5-10 times a minute, I would agree with @Usmann Butt and go for recompiling each time you call. Just be careful to monitor the server when the change is made to make sure you are not getting killed by recompiles. The change to
Jul 13 '12 at 09:56 AM
WilliamD
(comments are locked)
|
|
Please run sql profiler and find the query execution is same or different. What i am feeling is the query to needs to be corrected. if you can reply back with the query execution time for both from SSMS and EXE with same parameters and values, then we can proceed further. so i've run profiler on the server and it is literally just executing EXECUTE CustomerAdvancedSearch '', 'howe', '', '', '', '', ''
Jul 13 '12 at 11:47 AM
jhowe
@jhowe - as the other answers already discussed, the issue is one of parameter sniffing and not a direct query syntax/design issue. Implementing the R
Jul 13 '12 at 11:57 AM
WilliamD
(comments are locked)
|



and I bet if you run the alter script (as above) the app suddenly reports quick run times?
This is what the app is running EXEC customeradvancedsearch with various parameters
I totally agree with Kev Riley. Such search procedure cannot have a good plan for every scenario. It could run good for few scenarios and would be awful for some others, depending upon the data.
the DB isn't big, under 6gb i also reset DBCC SQLPERF ('sys.dm_os_wait_stats', CLEAR); fairly recently @Usman , yes but that is the issue i'm running the EXACT same query as the APP in SSMS and it is running sub second. The APP is HANGING i can't figure it out...
Have you tried OPTION(RECOMPILE) hint?