【发布时间】:2011-08-22 04:49:39
【问题描述】:
版本:SQL Server 2008 R2
数据库: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 将选择索引查找 + 键查找,完成速度更快,对 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 作为搜索谓词时,查询优化器规则和较差的基数估计也会导致优化器执行表或索引扫描操作而不是索引查找。
【问题讨论】:
-
SQL Server 将自动参数化一些查询 - 我不知道具体情况,但是,它可能正在尝试针对任何 LIKE ... 值优化上述内容,因此正在制作此特定搜索的错误计划选择。
-
@marc_s,如果你阅读了这个问题,你可以看到在没有任何查询提示的情况下,查询优化器将选择需要 500 倍以上 IO 的计划。也许它检测到我的磁盘处于空闲状态并渴望工作?这可能是一个很好的理由。无论如何,假设您确实再次阅读了该问题,您可以看到我在寻求一种方法来帮助查询优化器在不使用 FORCESEEK 的情况下选择更好的计划。
-
我不认为 SQL Server 会查看硬件并确定特定计划是好的,因为硬件当前空闲 - 计划创建成本很高。资源 - 制定计划时通常考虑重用。
-
@Will A,我在讽刺:P
标签: sql-server indexing query-hints