版:SQL Server 2008 R2的获取SQL Server使用索引查找+键查找,而不是聚集索引扫描,而不(FORCESEEK)
数据库:AdventureWorks的2008R2从http://msftdbprodsamples.codeplex.com/releases/view/55926
查询:
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将选择索引查找+键查找,完成速度更快,是500X亲切的IO:
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作为搜索寻求谓词。
SQL Server将自动参数化一些查询 - 我不知道具体情况,但是,它可能是它试图优化上面的任何LIKE ...值,并且因此正在为此做出糟糕的计划选择特定的搜索。 – 2011-05-10 06:36:59
@marc_s,如果您阅读了这个问题,您可以看到没有任何查询提示,查询优化器将选择需要500倍以上IO的计划。也许它发现我的磁盘闲置并渴望工作?这可能是一个很好的理由。无论如何,假设你再次读过这个问题,你可以看到我正在寻求一种方法来帮助查询优化器在没有FORCESEEK的情况下选择更好的计划。 – sayap 2011-05-10 06:38:43
我不认为SQL Server会查找硬件,并决定特定的计划是好的,因为硬件目前闲置 - 计划创建是昂贵的。资源 - 并且计划通常是在考虑到重用的情况下创建的。 – 2011-05-10 06:57:32