When the ROBUST PLAN hint is specified, the Query Optimizer does not consider any plans that might encounter this problem.. OPTIMIZE FOR can help improve optimization by allowing the Que
Trang 1FAST n—This hint instructs SQL Server to optimize the query to return the first n
rows as quickly as possible, even if the overall throughput is reduced In other
words, it improves response time at the expense of total query execution time This
option generally influences the Query Optimizer to retrieve data using a
nonclus-tered index that matches the ORDER BY clause of a query instead of using a different
access method that would require a sort operation first to return rows in the
speci-fied order After n number of rows have been returned, the query continues
execu-tion normally to produce its full result set
ROBUST PLAN—This option forces the Query Optimizer to attempt a plan that
works for the maximum potential row size, even if it means degrading performance
If you have very wide VARCHAR columns, some types of query plans might create
intermediate tables, and if any of the internal operations need to store and process
rows in these intermediate tables, some rows might exceed SQL Server’s row size
limit If this happens, SQL Server generates an error during query execution When
the ROBUST PLAN hint is specified, the Query Optimizer does not consider any plans
that might encounter this problem
MAXDOP number—This hint overrides the server-level configuration setting for max
degree of parallelism for the current query in which the hint is specified
KEEP PLAN—When this hint is specified, it forces the Query Optimizer to relax the
estimated recompile threshold for a query The estimated recompile threshold is the
point at which a query is automatically recompiled when the estimated number of
indexed column changes have been made to a table by updates, inserts, or deletes
Specifying KEEP PLAN ensures that the query is not recompiled as frequently when
there are multiple updates to a table This option is useful primarily for queries
whose execution plan stays in memory, such as for stored procedures You might
want to specify this option for a stored procedure that does a lot of work with
temporary tables, which can lead to frequent recompilations of the execution plan
for the stored procedure
KEEPFIXED PLAN—This query hint tells the Query Optimizer not to recompile the
query plan when there are changes in statistics or modifications to indexed columns
used by the query via updates, deletes, or inserts When this option is specified, the
query is recompiled only if the schema of the underlying tables is changed or
sp_recompile is executed against those tables
EXPAND VIEWS—This hint tells the Query Optimizer not to consider any indexed
view as a substitute for any part of the query and to force the view to be expanded
into its underlying query This hint essentially prevents direct use of indexed views
in the query plan
MAXRECURSION number—This hint specifies the maximum number of recursions
allowed for the common table expression query, where number is an integer between
0 and 32767 When 0 is specified, no limit is applied If this option is not specified,
the default limit for the server is 100 For more information on common table
Trang 2expressions and recursive queries, see Chapter 43, “Transact-SQL Programming
Guidelines, Tips, and Tricks.”
RECOMPILE—This hint forces SQL Server not to keep the execution plan generated
for the query in the plan cache after it executes This forces a new plan to be
gener-ated the next time the same or a similar query plan is executed RECOMPILE is useful
for queries with variable values that vary widely each time they are compiled and
executed This hint can be used for individual statements within a stored procedure
in place of the global WITH RECOMPILE option when you want only a subset of
queries inside the stored procedure to be recompiled rather than all of them
OPTIMIZE FOR ( @variable_name = literal_constant [ , n ] )—
This hint instructs SQL Server to use a specified value to optimize the SARGs for a
local variable that is otherwise unknown when the query is compiled and optimized
The value is used only during query optimization and not during query execution
OPTIMIZE FOR can help improve optimization by allowing the Query Optimizer to
use the statistics histogram rather than index densities to estimate the rows that
match the local variable, or can be used when you create plan guides
OPTIMIZE FOR UNKNOWN—This hint instructs the query optimizer to use statistical
data instead of the initial values for local variables when the query is compiled and
optimized, including parameters created with forced parameterization
TABLE HINT (object_name [ , table_hint [ [, ] n ] ] )—New in SQL
Server 2008, you can now specify table hints in the Query Hint OPTION clause It is
recommended that the TABLE HINT clause be used only in the context of a plan
guide For all other ad hoc queries, it is recommend that normal table hints be used
USE PLAN N’xml_plan’—This hint instructs SQL Server to use an existing query
plan for a query as specified by the designated xml_plan The USE PLAN query hint
can be used for queries whose plans result in slow execution times but for which you
know better plans exist
NOTE
Optimizer hints are not always executed For example, the Query Optimizer is likely to
ignore a HASH UNION hint for a query using the UNION ALL statement Because UNION
ALL means to return all rows whether or not there are duplicates, you don’t need to
hash these values to determine uniqueness and remove duplicates, so the normal
con-catenation is likely to still take place
Forced Parameterization
In SQL Server 2008, if a SQL statement is executed without parameters, the Query
Optimizer parameterizes the statement internally to increase the possibility of matching it
against an existing execution plan This process is called simple parameterization,
some-times referred to as auto-parameterization Simple parameterization is somewhat limited in
that it can parameterize only a relatively small number of queries that match a small
Trang 3number of very simple and strictly defined query templates For example, simple
parame-terization is not possible for queries that contain any of the following query elements:
References to more than one table
IN clauses or OR expressions
UNION
Any query hints
DISTINCT
TOP
Subqueries
GROUP BY
Not equal (<> or !=) comparisons
References to functions
SQL Server 2008 enables you to override the default simple parameterization behavior of
SQL Server and provide parameterization for more complex queries by specifying that all
SELECT, INSERT, UPDATE, and DELETE statements in a database be implicitly parameterized
when they are compiled by the Query Optimizer You enable this by setting the
PARAMETERIZATION option to FORCED in the ALTER DATABASE statement:
ALTER DATABASE dbname SET PARAMETERIZATION {FORCED | SIMPLE}
Setting the PARAMETERIZATION option is an online operation that can be issued at any time
and requires no database-level exclusive locks
Forced parameterization may improve the performance of queries for certain databases by
reducing the frequency of query compilations and recompilations Essentially, forced
para-meterization provides the query plan reuse benefits of parameterized queries without
requiring you to rewrite a single line of application code The databases that may benefit
from forced parameterization generally support OLTP-type applications that experience
high volumes of concurrent queries, such as point-of-sale applications
When the PARAMETERIZATION FORCED option is enabled, any literal value that appears in a
SELECT, INSERT, UPDATE, or DELETE statement, submitted in any form, is converted to a
parameter during query compilation The exceptions are literals that appear in the
follow-ing query constructs:
INSERT EXECUTE statements
Statements inside the bodies of stored procedures, triggers, or user-defined functions
SQL Server already reuses query plans for these routines
Prepared statements that have already been parameterized by the client-side
application
Statements inside a T-SQL cursor
Trang 4Any statement run in a context where ANSI_PADDING or ANSI_NULLS is set to OFF
Statements that contain more than 2,097 literals eligible for parameterization
Statements that reference variables, such as WHERE st.state = @state
Statements that contain the RECOMPILE or OPTIMIZE FOR query hints
Statements that contain a COMPUTE clause
Statements that contain a WHERE CURRENT OF clause
If an execution plan for a query is cached, you can determine whether the query is
para-meterized by referencing the sql column of the sys.syscacheobjects DMV If a query is
parameterized, the names and data types of parameters are listed in this column before
the text of the submitted SQL (for example, @1 tinyint)
Guidelines for Using Forced Parameterization
Consider the following guidelines when determining whether to enable forced
parameteri-zation for a database:
Forced parameterization, in effect, changes the literal constants in a query to
para-meters when the query is compiled, and thus, the Query Optimizer might choose
suboptimal plans for queries For example, the Query Optimizer may be less likely to
match the query to an indexed view or an index on a computed column It may also
choose suboptimal plans for queries posed on partitioned tables and distributed
partitioned views Forced parameterization should not be used for environments that
rely heavily on indexed views and indexes on computed columns
Enabling the PARAMETERIZATION FORCED option causes all query plans for the
data-base to be flushed from the plan cache
Generally, the PARAMETERIZATION FORCED option should be used only by experienced
database administrators after determining that doing this does not adversely affect
performance
If forced parameterization is enabled and you want to override this behavior and have
simple parameterization used for a single query and any others that are syntactically
equivalent but differ only in their parameter values, you can use plan guides and specify
PARAMETERIZATION SIMPLE when creating the plan guides Conversely, rather than
enabling PARAMETERIZATION FORCED for an entire database, you can use plan guides and
specify the PARAMETERIZATION FORCED query option only for a specific set of syntactically
equivalent queries that you have determined would benefit from forced parameterization
The USE PLAN query hint in SQL Server 2008 can be used to encourage the Query
Optimizer to use the specified XML query plan for processing the query This option
provides more control over influencing the execution of a query than is possible with the
other available query hints, such as FORCE ORDER, LOOP JOIN, and KEEP PLAN None of
these options individually are powerful enough to influence the Query Optimizer to
Trang 5consistently choose a particular query plan, especially when the referenced table row
counts, statistics, indexes, and other attributes of the environment change
The USE PLAN query hint is specified in the OPTION clause, and you provide it with a query
plan in XML format Listing 35.7 provides an example of the USE PLAN hint being
speci-fied for a merge join for a simple query that consists of a join between two tables (Note:
For the sake of space, the full XML plan has been truncated.)
LISTING 35.7 Specifying the USE PLAN Query Option
select st.stor_name, s.ord_date
from sales s join stores st on s.stor_id = st.stor_id
WHERE st.state = ‘NY’
OPTION (USE PLAN N’
<?xml version=”1.0” encoding=”utf-16”?>
<ShowPlanXML xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xmlns:xsd=”http://www.w3.org/2001/XMLSchema” Version=”1.1”
Build=”10.50.1352.12” xmlns=”http://schemas.microsoft.com/
sqlserver/2004/07/showplan”>
<BatchSequence>
<Batch>
<Statements>
<StmtSimple StatementCompId=”1” StatementEstRows=”10710.8”
StatementId=”1” StatementOptmLevel=”FULL” StatementSubTreeCost=”1.71032”
StatementText=”select st.stor_name, s.ord_date
 from sales s join
stores st on s.stor_id = st.stor_id
 WHERE st.state =
‘’NY’’
” StatementType=”SELECT” QueryHash=”0x35DE42B697A8BAAF
“ QueryPlanHash=”0x9F4AE50605763B05”>
<StatementSetOptions ANSI_NULLS=”true” ANSI_PADDING=”true”
ANSI_WARNINGS=”true” ARITHABORT=”true” CONCAT_NULL_YIELDS_NULL=”true”
NUMERIC_ROUNDABORT=”false” QUOTED_IDENTIFIER=”true” />
<QueryPlan DegreeOfParallelism=”1” CachedPlanSize=”16” CompileTime=”6”
CompileCPU=”6” CompileMemory=”232”>
<MissingIndexes>
<MissingIndexGroup Impact=”13.6636”>
<MissingIndex Database=”[bigpubs2008]” Schema=”[dbo]”
Table=”[stores]”>
<ColumnGroup Usage=”EQUALITY”>
<Column Name=”[state]” ColumnId=”5” />
</ColumnGroup>
<ColumnGroup Usage=”INCLUDE”>
<Column Name=”[stor_id]” ColumnId=”1” />
<Column Name=”[stor_name]” ColumnId=”2” />
</ColumnGroup>
</MissingIndex>
</MissingIndexGroup>
Trang 6</MissingIndexes>
<RelOp AvgRowSize=”39” EstimateCPU=”0.363144” EstimateIO=”0”
EstimateRebinds=”0” EstimateRewinds=”0” EstimateRows=”10710.8”
LogicalOp=”Inner Join” NodeId=”0” Parallel=”false” PhysicalOp=”Merge Join”
EstimatedTotalSubtreeCost=”1.71032”>
<Object Database=”[bigpubs2008]” Schema=”[dbo]” Table=”[sales]”
Index=”[UPKCL_sales]” Alias=”[s]” IndexKind=”Clustered” />
</IndexScan>
</RelOp>
</Merge>
</RelOp>
</QueryPlan>
</StmtSimple>
</Statements>
</Batch>
</BatchSequence>
</ShowPlanXML>
To obtain an XML-formatted query plan, which you can provide to the USE PLAN query
hint, SQL Server 2008 provides the following methods:
Using the SET SHOWPLAN_XML and SET STATISTICS XML session options
Querying the plan column of the sys.dm_exec_query_plan dynamic management
view for a cached query plan
Using SQL Server Profiler and capturing either the Showplan XML, Showplan XML
Statistics Profile, or Showplan XML For Query Compile event classes
NOTE
When the XML query plan contains a character string in single quotation marks (‘), the
quotation marks must be escaped by a second quotation mark before using the plan
with the USE PLAN query hint For example, a plan that contains WHERE A.varchar =
‘This is a string’ must be escaped by modifying the code to WHERE A.varchar
= ‘’This is a string’’; otherwise, it will generate a syntax error when submitted
for execution
You may choose to use the USE PLAN hint for queries where the execution plan chosen
leads to slow execution times but for which you know a better plan exists This scenario
may commonly occur for queries that might have executed well in an earlier version of
SQL Server but that perform poorly under an upgraded version Another scenario could
be a complex query that involves multiple tables where the compiled or recompiled query
plan generated is occasionally not optimal, possibly as a result of out-of-date or missing
statistics in any of the underlying tables or because of complex constructs in the query
Trang 7that cause the Query Optimizer to inaccurately estimate the size of the intermediate
query results
The USE PLAN query hint can be specified only for SELECT and SELECT INTO statements
Also, you can force only query plans that can be produced by the Query Optimizer’s
normal optimization strategy
Because the USE PLAN option requires that the XML execution plan be hard-coded in the
SQL statement itself, it is not a viable solution for deployed or third-party applications
where it may not be possible or feasible to modify the queries directly It’s really useful
only as a tool for troubleshooting poorly running queries To force query plans to apply
query hints to queries when you cannot or do not want to directly change the application
or SQL code, you might consider using plan guides
Using Plan Guides
At times, you might find it necessary to use query hints to improve the performance of
queries for a particular query or a small set of queries Although this may be easy to do
when you have access to the application code, often the particular queries to be modified
are embedded within a third-party application, and alteration of the queries themselves is
virtually impossible Also, if you start hard-coding query hints in your application code,
changing them as necessary when data volumes change or when upgrading to a new
version of SQL Server can be a difficult undertaking
The plan guides feature in SQL Server 2008 provides an ideal solution for such scenarios
by offering another mechanism for injecting query hints into the original query without
having to modify the query itself The plan guides mechanism uses an internal lookup
system table, based on information in the sys.plan_guides catalog view, to map the
origi-nal query to a substitute query or query template
As described earlier in this chapter, when a SQL statement is submitted, it is first
compared against the cached plans to check for a match If a match exists, the cached
query plan is used to execute the query If no cached plan exists for the query, the Query
Optimizer next looks for a match against the set of existing plan guides, if any, stored in
the current database for a match If an active plan guide that matches the SQL statement
is found, the original matching statement is substituted with the one from the plan guide,
the query plan is compiled and cached, and the query is executed using the plan
gener-ated from the plan guide
Queries that can benefit from plan guides are generally those that are parameter based and
those that are likely performing poorly because they use cached query plans whose
para-meter values do not represent a more representative scenario
The plan guides feature essentially consists of two stored procedures to create, drop,
enable, and disable plan guides and the sys.plan_guides metadata view that describes the
stored plan guides Plan guides are created and administered by using the two system
stored procedures:
sp_create_plan_guide
Trang 8sp_control_plan_guide
The syntax for these procedures is as follows:
sp_create_plan_guide [ @name = ] N’plan_guide_name’
, [ @stmt = ] N’statement_text’
, [ @type = ] N’{ OBJECT | SQL | TEMPLATE }’
, [ @module_or_batch = ]
{
N’[ schema_name ] object_name’
| N’batch_text’
| NULL
}
, [ @params = ] { N’@parameter_name data_type [ , n ]’ | NULL }
, [ @hints = ] { N’OPTION ( query_hint [ , n ] )’
| N’XML_execution plan’
| NULL } sp_control_plan_guide [ @operation = ] N’<control_option>’
[ , [ @name = ] N’plan_guide_name’ ]
<control_option>::=
{
DROP
| DROP ALL
| DISABLE
| DISABLE ALL
| ENABLE
| ENABLE ALL
}
Note that in SQL Server 2008, the sp_create_plan_guide stored procedure enables you to
pass an XML execution plan directly in the @hints parameter instead of embedding the
output in a USE PLAN hint This capability simplifies the process of applying a fixed query
plan as a plan guide hint
In addition, a new stored procedure, sp_create_plan_guide_from_handle, allows you to
create one or more plan guides from a query plan in the plan cache The syntax for
sp_create_plan_guide_from_handle is as follows:
sp_create_plan_guide_from_handle [ @name = ] N’plan_guide_name’
, [ @plan_handle = ] plan_handle
, [ [ @statement_start_offset = ] { statement_start_offset | NULL } ]
Instead of specifying an actual XML execution plan, you pass the handle for a query plan
currently in the plan cache to the @plan_handle parameter As shown previously in this
chapter, a plan_handle can be obtained from the sys.dm_exec_query_stats DMV If the
Trang 9cached plan contains multiple queries in a SQL batch, you can specify the starting
posi-tion of the statement within the batch via the @statement_start_offset parameter The
statement offset corresponds to the statement_start_offset column in the
sys.dm_exec_query_stats dynamic management view If no statement offset is specified,
a plan guide is created for each statement in the batch using the query plan for the
speci-fied plan handle The resulting plan guides are equivalent to plan guides that use the USE
PLAN query hint to force the use of a specific plan
Creating Plan Guides
Plan guides can be created to match queries executed in the following contexts:
An OBJECT plan guide matches queries that execute in the context of T-SQL stored
procedures, scalar functions, or multistatement table-valued functions
A SQL plan guide matches queries that execute in the context of ad hoc T-SQL
state-ments and batches that are not part of a stored procedure or other compiled
data-base object
A TEMPLATE plan guide matches ad hoc queries that parameterize to a specified
form These plan guides are used to override the current SET PARAMETERIZATION
database option
In the sp_create_plan_guide statement, you specify the query that you want optimized
and provide the OPTION clause with the query hints necessary to optimize the query in the
manner desired, or an XML execution plan for the query plan you want the query to use
When the query executes, SQL Server matches the query to the plan guide and applies the
forced query plan to the query at runtime
The plan guide can specify any of the following query hints individually or combined
with others, when applicable:
{HASH | ORDER} GROUP
{CONCAT | HASH | MERGE} UNION
{LOOP | MERGE | HASH} JOIN
FAST n
FORCE ORDER
MAXDOP number_of_processors
OPTIMIZE FOR ( @variable_name = literal_constant ) [ , n ]
OPTIMIZE FOR UNKNOWN
RECOMPILE
ROBUST PLAN
KEEP PLAN
KEEPFIXED PLAN
Trang 10EXPAND VIEWS
MAXRECURSION number
TABLE HINT (object_name [ , table_hint [ [, ] n ] ] )
USE PLAN <xmlplan>
PARAMETERIZATION { SIMPLE | FORCED }
The PARAMETERIZATION { SIMPLE | FORCED } query hint can be used only within a plan
guide, and it specifies whether a query is parameterized as part of compiling a query plan
This option overrides the current setting of the PARAMETERIZATION option set at the
data-base level
Listing 35.8 provides a sample plan guide created for a simple SQL statement
LISTING 35.8 Creating a Plan Guide for a Simple SQL Statement
sp_create_plan_guide @name = N’PlanGuide1’,
@stmt = N’SELECT COUNT(*) AS Total
FROM dbo.sales s, dbo.titles t
WHERE s.title_id = t.title_id
and t.pubdate BETWEEN ‘’1/1/2004’’ AND ‘’1/1/2006’’
‘,
@type = N’SQL’,
@module_or_batch = NULL,
@params = NULL,
@hints = N’OPTION (HASH JOIN)’
For plan guides of type ’SQL’ or ’TEMPLATE’ to match a query successfully, the values for
batch_text and @parameter_name data_type [, n ] must be provided in exactly the
same format as their counterparts submitted by the application Specifically, they must
match character for character, including comments and whitespaces
TIP
When you are creating plan guides, be careful to specify the query in the @stmt
para-meter and any parapara-meter names and values in the @params parameter exactly as they
are received from the application The best way to ensure this is to capture the batch
or statement text from SQL Server Profiler (See Chapter 6 for more information on
using SQL Server Profiler to capture SQL queries.) Also, as with the XML query plans
passed to the USE PLAN query hint, single-quoted literal values, such as ’1/1/2000’,
need to be delimited with single quotation marks escaped by additional single
quota-tion marks, as shown in Listing 35.6
Managing Plan Guides
You use the sp_control_plan_guide stored procedure to enable, disable, or drop a plan
guide The following example drops the plan guide created in Listing 35.8: