版本:SQL Server 2008 R2
数据库:来自http://msftdbprodsamples.codeplex.com/releases/view/55926的 AdventureWorks 2008R2
询问:
SELECT TOP 10
*
FROM
Person.Person --WITH (FORCESEEK)
WHERE
LastName like 'Max%'
OR EXISTS (
SELECT
1
FROM
Person.PersonPhone
WHERE
Person.PersonPhone.BusinessEntityID = Person.Person.BusinessEntityID
AND Person.PersonPhone.PhoneNumber LIKE '122%'
)
ORDER BY Person.Person.BusinessEntityID DESC
在没有任何查询提示的情况下,SQL Server 将使用聚集索引扫描,这是 IO 密集型的:
Table 'PersonPhone'. Scan count 14170, logical reads 28446, physical reads 15, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Person'. Scan count 1, logical reads 2844, physical reads 3, read-ahead reads 3215, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
使用WITH (FORCESEEK)
查询提示,SQL Server 将选择索引查找 + 键查找,完成速度更快,对 IO 友好 500 倍:
Table 'Person'. Scan count 1, logical reads 59, physical reads 22, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'PersonPhone'. Scan count 1, logical reads 2, physical reads 2, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
我的问题是,有没有办法让 SQL Server 在没有任何查询提示的情况下使用更好的计划?也许添加索引?还是更改配置参数?还是 SQL Server 的查询优化器那么笨?
这是来自http://msdn.microsoft.com/en-us/library/bb510478.aspx的宝石:
当查询使用 IN 或 LIKE 作为搜索谓词时,查询优化器规则和较差的基数估计也会导致优化器执行表或索引扫描操作而不是索引查找。