The FORCESEEK
table hint was introduced in SQL Server 2008 to force an index seek in
an execution plan in place of an index scan. The query optimizer does a
really good job deciding whether a seek or scan is more efficient, but
in certain scenarios you may want to override the execution plan's
decision. For example, poor cardinality estimation using the LIKE and IN
operators may cause the query optimizer to choose an index scan when an
index seek may be more efficient. Another reason for a poor execution
plan could be due to plan reuse. For example, an execution plan could be
initially generated using parameters that were more efficient using a
scan, and now the plan is reused several times for parameters that would
be more efficient using a seek. Take a look at the query in Listing 1.
Example 1. Query to Create a Clustered Index Scan
USE AdventureWorks2008 GO
SELECT * FROM HumanResources.Employee A JOIN HumanResources.EmployeeDepartmentHistory B ON A.BusinessEntityID = B.BusinessEntityID WHERE A.BusinessEntityID > 270 OR (A.BusinessEntityID < 10 and B.DepartmentID =1)
|
As you can see in Figure 1, the query in Listing 1
used a clustered index scan on the EmployeeDepartmentHistory table, and
then used a merge join to combine the results with the Employee table.
Now let's see what happens when we execute the same query using the FORCESEEK table hint by running the query in Listing 2.
Example 2. Query to Force a Clustered Index Seek
USE AdventureWorks2008 GO
SELECT * FROM HumanResources.Employee A JOIN HumanResources.EmployeeDepartmentHistory B WITH (FORCESEEK) ON A.BusinessEntityID = B.BusinessEntityID WHERE A.BusinessEntityID > 270 OR (A.BusinessEntityID < 10 and B.DepartmentID =1)
|
As you can see in Figure 2, using the FORCESEEK
table hint caused the same query to use a clustered index seek on the
EmployeeDepartmentHistory table, and the results are now joined with the
Employee table using nested loops.
Both of these execution
plans provide almost identical performance metrics because the result
set is so small. However, as the parameters change and the result set
gets larger, the execution plan originally chosen by the query optimizer
will outperform the execution plan generated using the FORCESEEK option.
Before considering using the FORCESEEK
table hint, you should make sure the statistics for the database are up
to date. In most cases, the query optimizer will choose the best
execution plan for a query, but in rare cases, the FORCESEEK table hint could prove to be a very useful new feature.