I've read up on the SQL Server 2008 OPTIMIZE FOR UNKNOWN query hint. I understand how it works.
However, I have a question on where and when to use it. It cannot be specified inside a UDF. It can be specified inside a stored proc. However, this MSDN blog post states the following:
4.Moving a query into a stored procedure can put it into a separate procedural context and can be a good way to get that value visible to the optimizer (Note: this works in SQL 2000 as well)
That seems to me to be saying that any parameter passed to a stored proc will be "sniffed", thereby helping SQL Server to compile an optimum execution plan. This is implying that the cached plan would be revisited/recompiled (not sure of that mechanism). However, this is confusing, because it negates the whole need for OPTIMIZE FOR UNKNOWN.
The MSDN article on query hints doesn't cover my question.
Can someone answer this for me, ideally with a pointer to something from Microsoft that clears this up. Thanks.
The default behaviour of the SQL compiler is to use the values of any parameters given in the first execution of an SP to help optimise the plan (see paragraphs 2 and 3 of this MSDN article on SP recompilation). That plan is then cached for re-use until it leaves the cache - lots of detail on the plan caching process here.
The MSDN blog you cite is noting ways to make this process easier for the compiler; I think item 4 (quoted in the question) is suggesting that this is an advantage of stored procedures over ad-hoc SQL.
The OPTIMIZE FOR UNKNOWN
hint instructs the compiler to aviod the default behaviour; that it should ignore the parameter values given in the first execution and select a more generalised plan. This is a more extreme version of item 2 in the list of suggestions at the end of the blog post cited in the question;
2 If you find that the optimizer is picking different plans over time that have varying performance characteristics, consider using a parameter hint with a representative “average” value to get a good, common query plan that will work reasonably for all values.
but rather than selecting an average or representative value, the compiler will effectively ignore the parameter values entirely.
Consider using OPTIMIZE FOR UNKNOWN
in the circumstances given quoted in item 2 - when the same query gives very variable performance because the plan is poor in some circumstances - typically when parameters in the query filter columns of very variable cardinality.
来源:https://stackoverflow.com/questions/4352188/stored-procedures-and-optimize-for-unknown