日期:2014-05-17  浏览次数:20664 次

一点点的改动为什么执行计划差别如此之大
数据库环境:
2008R2的数据库,数据库:AdventureWorks

语句与计划执行:
SELECT e.EmployeeID 
FROM HumanResources.Employee AS e 
INNER JOIN Sales.SalesPerson AS s ON e.EmployeeID = s.SalesPersonID

SELECT s.SalesPersonID 
FROM HumanResources.Employee AS e 
INNER JOIN Sales.SalesPerson AS s ON e.EmployeeID = s.SalesPersonID


SalesPerson是17行,Employee是290行
索引信息:
表SalesPerson


表Employee


有AdventureWorks库的可以详细的看看,为什么显示所用的表不同但执行计划会差的那么多,请各位详解,最近正在学习执行计划有这方面的资料的话请推荐越详细越好。
SQL执行计划 索引

------解决方案--------------------
因为 FOREIGN KEY:
Sales.SalesPerson.SalesPersonID REFERENCES HumanResources.Employee.EmployeeID

所以第二句直接把 INNER JOIN 砍掉了:
SELECT s.SalesPersonID  FROM Sales.SalesPerson AS s
------解决方案--------------------
2楼说的有道理。
第二个查询实际上只访问了SalesPerson一个表,因为优化器足够聪明,他发现你要输出的行不在关联表中(Employee),并且两个表存在外键,所以他仅仅扫描了SalesPerson表的非聚集索引,因为SalesPersonID 是SalesPerson的主键,所以直接在SalesPerson表的非聚集索引页级可以找到所需数据。逻辑扫描2次,因为索引是两层。
第一个查询需要扫描两个表,因为此时外键在SalesPerson表,索引先查找SalesPerson表,17条记录,再在Employee表上聚集索引上查找数据,该聚集索引2级,共34次逻辑读。
从逻辑读大概知道查询一比查询二的性能开销大得多。