Avoiding Optimizer Hints
Avoiding Optimizer Hints
SQL Server’s cost-based optimizer dynamically determines the processing strategy for a
query based on the current table/index structure and data. This dynamic behavior can be
overridden using optimizer hints, taking some of the decisions away from the optimizer by
instructing it to use a certain processing strategy. This makes the optimizer behavior static
and doesn’t allow it to dynamically update the processing strategy as the table/index
structure or data changes.
Since it is usually difficult to outsmart the optimizer, the usual recommendation is to avoid
optimizer hints. Generally, it is beneficial to let the optimizer determine a cost-effective
processing strategy based on the data distribution statistics, indexes, and other factors.
Forcing the optimizer (with hints) to use a specific processing strategy hurts performance
more often than not, as shown in the following examples for these hints:
JOIN hint
INDEX hint
FORCEPLAN hint
Join Hints
The optimizer dynamically determines a cost-effective JOIN strategy between two data
sets based on the table/index structure and data. Table below presents a summary of the
JOIN types supported by SQL Server.
You can instruct SQL Server to use a specific JOIN type by using the JOIN hints in Table above.
To understand how the use of JOIN hints can affect performance, consider the following
SELECT statement.
JOIN hints force the optimizer to ignore its own optimization strategy and use instead the
strategy specified by the query. JOIN hints generally hurt query performance because of
the following factors:
INDEX Hints
As mentioned earlier, using an arithmetic operator on a WHERE clause column prevents
the optimizer from choosing the index on the column. To improve performance, you can
rewrite the query without using the arithmetic operator on the WHERE clause, as shown
in the corresponding example. Alternatively,
You can force the optimizer to use the index on the column with an INDEX hint (a type of
optimizer hint). However, most of the time, it is better to avoid the INDEX hint and let the
optimizer be have dynamically.
To understand the effect of an INDEX hint on query performance, consider the example:
SELECT *
FROM Purchasing.PurchaseOrderHeader AS poh ---WITH (INDEX
(PK_PurchaseOrderHeader_PurchaseOrderID))
WHERE poh.PurchaseOrderID * 2 = 3400 ;
The multiplication operator on the PurchaseOrderID column prevented the optimizer from
choosing the index on the column. You can use an INDEX hint to force the optimizer to use
the index on the OrderID column as follows:
SELECT *
FROM Purchasing.PurchaseOrderHeader AS poh WITH (INDEX
(PK_PurchaseOrderHeader_PurchaseOrderID))
WHERE poh.PurchaseOrderID * 2 = 3400 ;
---query without Index hint and use of arithmetic operator on the right side of the
comparison operator not left side on the column
SELECT *
FROM Purchasing.PurchaseOrderHeader AS poh ---WITH (INDEX
(PK_PurchaseOrderHeader_PurchaseOrderID))
WHERE poh.PurchaseOrderID = 3400/2 ;