A. Using MERGE JOIN
The following example specifies that the JOIN operation in the query is performed by MERGE JOIN.
B. Using OPTIMIZE FOR
The following example instructs the query optimizer to use the value 'Seattle' for local variable@city_name and to use statistical data to determine the value for the local variable @postal_code when optimizing the query.
USE AdventureWorks2008R2; GO DECLARE @city_name nvarchar(30); DECLARE @postal_code nvarchar(15); SET @city_name = 'Ascheim'; SET @postal_code = 86171; SELECT * FROM Person.Address WHERE City = @city_name AND PostalCode = @postal_code OPTION ( OPTIMIZE FOR (@city_name = 'Seattle', @postal_code UNKNOWN) ); GO
C. Using MAXRECURSION
MAXRECURSION can be used to prevent a poorly formed recursive common table expression from entering into an infinite loop. The following example intentionally creates an infinite loop and uses the MAXRECURSION hint to limit the number of recursion levels to two.
USE AdventureWorks2008R2; GO --Creates an infinite loop WITH cte (CustomerID, PersonID, StoreID) AS ( SELECT CustomerID, PersonID, StoreID FROM Sales.Customer WHERE PersonID IS NOT NULL UNION ALL SELECT cte.CustomerID, cte.PersonID, cte.StoreID FROM cte JOIN Sales.Customer AS e ON cte.PersonID = e.CustomerID ) --Uses MAXRECURSION to limit the recursive levels to 2 SELECT CustomerID, PersonID, StoreID FROM cte OPTION (MAXRECURSION 2); GO
After the coding error is corrected, MAXRECURSION is no longer required.
D. Using MERGE UNION
The following example uses the MERGE UNION query hint.
E. Using HASH GROUP and FAST
The following example uses the HASH GROUP and FAST query hints.
F. Using MAXDOP
The following example uses the MAXDOP query hint. (Parallel query)
G. Using INDEX
The following examples use the INDEX hint. The first example specifies a single index. The second example specifies multiple indexes for a single table reference. In both examples, because the INDEX hint is applied on a table that uses an alias, the TABLE HINT clause must also specify the same alias as the exposed object name.
USE AdventureWorks2008R2; GO EXEC sp_create_plan_guide @name = N'Guide1', @stmt = N'SELECT c.LastName, c.FirstName, e.JobTitle FROM HumanResources.Employee AS e JOIN Person.Person AS c ON e.BusinessEntityID = c.BusinessEntityID WHERE e.OrganizationLevel = 2;', @type = N'SQL', @module_or_batch = NULL, @params = NULL, @hints = N'OPTION (TABLE HINT(e, INDEX (IX_Employee_OrganizationLevel_OrganizationNode)))'; GO EXEC sp_create_plan_guide @name = N'Guide2', @stmt = N'SELECT c.LastName, c.FirstName, e.JobTitle FROM HumanResources.Employee AS e JOIN Person.Person AS c ON e.BusinessEntityID = c.BusinessEntityID WHERE e.OrganizationLevel = 2;', @type = N'SQL', @module_or_batch = NULL, @params = NULL, @hints = N'OPTION (TABLE HINT(e, INDEX(PK_Employee_BusinessEntityID, IX_Employee_OrganizationLevel_OrganizationNode)))'; GO
H. Using FORCESEEK
The following example uses the FORCESEEK table hint. Because the INDEX hint is applied on a table that uses a two-part name, the TABLE HINT clause must also specify the same two-part name as the exposed object name.
USE AdventureWorks2008R2; GO EXEC sp_create_plan_guide @name = N'Guide3', @stmt = N'SELECT c.LastName, c.FirstName, HumanResources.Employee.JobTitle FROM HumanResources.Employee JOIN Person.Person AS c ON HumanResources.Employee.BusinessEntityID = c.BusinessEntityID WHERE HumanResources.Employee.OrganizationLevel = 3 ORDER BY c.LastName, c.FirstName;', @type = N'SQL', @module_or_batch = NULL, @params = NULL, @hints = N'OPTION (TABLE HINT( HumanResources.Employee, FORCESEEK))'; GO
I. Using multiple table hints
The following example applies the INDEX hint to one table and the FORCESEEK hint to another.
USE AdventureWorks2008R2;
GO
EXEC sp_create_plan_guide
@name = N'Guide4',
@stmt = N'SELECT c.LastName, c.FirstName, e.JobTitle
FROM HumanResources.Employee AS e
JOIN Person.Person AS c ON e.BusinessEntityID = c.BusinessEntityID
WHERE OrganizationLevel = 3;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT ( e, INDEX( IX_Employee_OrganizationLevel_OrganizationNode ) ),
TABLE HINT ( c, FORCESEEK) )';
GO
J. Using TABLE HINT to override an existing table hint
The following example shows how to use the TABLE HINT hint without specifying a hint to override the behavior of the INDEX table hint specified in the FROM clause of the query.
USE AdventureWorks2008R2; GO EXEC sp_create_plan_guide @name = N'Guide5', @stmt = N'SELECT c.LastName, c.FirstName, e.JobTitle FROM HumanResources.Employee AS e WITH (INDEX (IX_Employee_OrganizationLevel_OrganizationNode)) JOIN Person.Person AS c ON e.BusinessEntityID = c.BusinessEntityID WHERE OrganizationLevel = 3;', @type = N'SQL', @module_or_batch = NULL, @params = NULL, @hints = N'OPTION (TABLE HINT(e))'; GO
K. Specifying semantics-affecting table hints
The following example contains two table hints in the query: NOLOCK, which is semantic-affecting, and INDEX, which is non-semantic-affecting. To preserve the semantics of the query, the NOLOCK hint is specified in the OPTIONS clause of the plan guide. In addition to the NOLOCK hint, the INDEX and FORCESEEK hints are specified and replace the non-semantic-affecting INDEX hint in the query when the statement is compiled and optimized.
USE AdventureWorks2008R2; GO EXEC sp_create_plan_guide @name = N'Guide6', @stmt = N'SELECT c.LastName, c.FirstName, e.JobTitle FROM HumanResources.Employee AS e JOIN Person.Person AS c ON e.BusinessEntityID = c.BusinessEntityID WHERE OrganizationLevel = 3;', @type = N'SQL', @module_or_batch = NULL, @params = NULL, @hints = N'OPTION (TABLE HINT ( e, INDEX( IX_Employee_OrganizationLevel_OrganizationNode), NOLOCK, FORCESEEK ))'; GO
The following example shows an alternative method to preserving the semantics of the query and allowing the optimizer to choose an index other than the index specified in the table hint. This is done by specifying the NOLOCK hint in the OPTIONS clause (because it is semantic-affecting) and specifying the TABLE HINT keyword with only a table reference and no INDEX hint.
USE AdventureWorks2008R2; GO EXEC sp_create_plan_guide @name = N'Guide7', @stmt = N'SELECT c.LastName, c.FirstName, e.JobTitle FROM HumanResources.Employee AS e JOIN Person.Person AS c ON e.BusinessEntityID = c.BusinessEntityID WHERE OrganizationLevel = 2;', @type = N'SQL', @module_or_batch = NULL, @params = NULL, @hints = N'OPTION (TABLE HINT ( e, NOLOCK))'; GO
Query hints affect all operators in the query.
Query hints cannot be specified in an INSERT statement except when a SELECT clause is used inside the statement.
Query hints can be specified only in the top-level query, not in subqueries. When a table hint is specified as a query hint, the hint can be specified in the top-level query or in a subquery; however, the value specified for exposed_object_name in the TABLE HINT clause must match exactly the exposed name in the query or subquery.
If UNION is involved in the main query, only the last query involving a UNION operation can have the OPTION clause. Query hints are specified as part of the OPTION clause. If one or more query hints cause the query optimizer not to generate a valid plan, error 8622 is raised.
Specifying Table Hints as Query Hints
We recommend using the INDEX or FORCESEEK table hint as a query hint only in the context of a plan guide. Plan guides are useful when you cannot modify the original query, for example, because it is a third-party application. The query hint specified in the plan guide is added to the query before it is compiled and optimized. For ad-hoc queries, use the TABLE HINT clause only when testing plan guide statements. For all other ad-hoc queries, we recommend specifying these hints only as table hints.
When specified as a query hint, the INDEX, FORCESCAN and FORCESEEK table hints are valid for the following objects:
Tables
Views
Indexed views
Common table expressions (The hint must be specified in the SELECT statement whose result set populates the common table expression.)
Dynamic management views
Named subqueries
The INDEX, FORCESCAN, and FORCESEEK table hints can be specified as query hints for a query that does not have any existing table hints, or they can be used to replace existing INDEX, FORCESCAN or FORCESEEK hints in the query, respectively. Table hints other than INDEX, FORCESCAN and FORCESEEK are disallowed as query hints unless the query already has a WITH clause specifying the table hint. In this case, a matching hint must also be specified as a query hint by using TABLE HINT in the OPTION clause to preserve the semantics of the query. For example, if the query contains the table hint NOLOCK, the OPTION clause in the @hints parameter of the plan guide must also contain the NOLOCK hint. See Example K. When a table hint other than INDEX, FORCESCAN, or FORCESEEK is specified by using TABLE HINT in the OPTION clause without a matching query hint, or vice versa; error 8702 is raised (indicating that the OPTION clause can cause the semantics of the query to change) and the query fails. For more information, see Using the INDEX and FORCESEEK Query Hints in Plan Guides.
Reference
Other Resources
Reference : http://msdn.microsoft.com/en-us/library/ms181714.aspx
'SQL' 카테고리의 다른 글
2011. 03 월 2회 SQLP 도전 --- 결과 ^^ (작성중) (1) | 2011.08.03 |
---|---|
Full Outer Join (0) | 2011.07.22 |
Recursive CTE Structure [ ;WITH .... AS (... UNION ALL ...) SELECT ] (0) | 2011.07.22 |
CREATE OR REPLACE PROCEDURE EJMIS.Ledger_Migration_Daily (0) | 2011.07.20 |
SYS_CONNECT_BY_PATH (0) | 2011.07.15 |