内部联接会导致查询性能下降

时间:2017-09-25 19:34:55

标签: sql sql-server

除了JOIN到mjnEmployeeDepartment之外,下面有两个查询相同。第一个查询使用LEFT OUTER JOIN,第二个查询使用INNER JOIN。它们都返回相同的数据,但INNER JOIN需要4.5分钟才能执行,而LEFT OUTER JOIN需要4秒。任何人都可以建议这里可能会发生什么?

我正在SMS 2017中针对SQL 2012数据库运行代码。

Select
Count(*) --23878 00:00:00

From
       dbo.mjnEmployee as e
              Inner Join dbo.mjnEmployeeStatus as s
                     on e.EmployeeID = s.EmployeeID
              Inner Join dbo.mjnEmployeeEmploymentInfo as RankNo
                     On e.EmployeeId = RankNo.EmployeeID
              Inner Join dbo.mjnEmployeeOfficeAssociation as Office
                     On e.EmployeeId = Office.EmployeeID
              Inner Join dbo.mjnEmployeeEmploymentInfo as TrackNo
                     On e.EmployeeId = TrackNo.EmployeeID
              Inner Join dbo.mjnEmployeeUnit as Unit
                     on e.EmployeeID = Unit.EmployeeID
                     And Unit.Iteration = 1

              Left Outer Join dbo.mjnEmployeeDepartment as Department
                     on e.EmployeeID = Department.EmployeeID

              Left Outer Join dbo.mjnEmployeeAssociation as Supervisor
                     On  e.EmployeeId = Supervisor.ObjectEmployeeId
                     and Supervisor.EmployeeAssociationType = 2
              Left Outer Join dbo.mjnEmployeeAssociation as Manager
                     On Manager.ObjectEmployeeId = e.EmployeeId
                     and Manager.EmployeeAssociationType = 1
              Left Outer Join dbo.mjnEmployeeAssociation as Assistant
                     On  e.EmployeeId = Assistant.ObjectEmployeeId
                     and Assistant.EmployeeAssociationType = 3
              Left Outer Join dbo.mjnEmployeeAssociation as Advisor
                     On e.EmployeeId = Advisor.ObjectEmployeeId
                     and Advisor.EmployeeAssociationType = 4

Select
Count(*) --23878 00:04:37

From
       dbo.mjnEmployee as e
              Inner Join dbo.mjnEmployeeStatus as s
                     on e.EmployeeID = s.EmployeeID
              Inner Join dbo.mjnEmployeeEmploymentInfo as RankNo
                     On e.EmployeeId = RankNo.EmployeeID
              Inner Join dbo.mjnEmployeeOfficeAssociation as Office
                     On e.EmployeeId = Office.EmployeeID
              Inner Join dbo.mjnEmployeeEmploymentInfo as TrackNo
                     On e.EmployeeId = TrackNo.EmployeeID
              Inner Join dbo.mjnEmployeeUnit as Unit
                     on e.EmployeeID = Unit.EmployeeID
                     And Unit.Iteration = 1

              Inner Join dbo.mjnEmployeeDepartment as Department
                     on e.EmployeeID = Department.EmployeeID

              Left Outer Join dbo.mjnEmployeeAssociation as Supervisor
                     On  e.EmployeeId = Supervisor.ObjectEmployeeId
                     and Supervisor.EmployeeAssociationType = 2
              Left Outer Join dbo.mjnEmployeeAssociation as Manager
                     On Manager.ObjectEmployeeId = e.EmployeeId
                     and Manager.EmployeeAssociationType = 1
              Left Outer Join dbo.mjnEmployeeAssociation as Assistant
                     On  e.EmployeeId = Assistant.ObjectEmployeeId
                     and Assistant.EmployeeAssociationType = 3
              Left Outer Join dbo.mjnEmployeeAssociation as Advisor
                     On e.EmployeeId = Advisor.ObjectEmployeeId
                     and Advisor.EmployeeAssociationType = 4

3 个答案:

答案 0 :(得分:0)

似乎下面的表中使用的连接缺失on子句会导致所有行与前面的结果相乘,

Inner Join dbo.mjnEmployeeDepartment as Department
                     on e.EmployeeID = Department.EmployeeID

是否有其他表格有此列?如果是,则需要使用。

答案 1 :(得分:0)

我们最终使用了重新排序表并使用FORCESEEK优化器提示的组合。我们将条件连接表移动到所有内连接表之后,并在department表之后添加WITH(FORCESEEK)。现在像一个冠军一样跑。

答案 2 :(得分:-1)

您需要查看内部和外部联接之间的区别。实质上,内部联接将给出两个表共有的行,其中外部联接将给出表A中的所有行以及表B中匹配的任何行。

这可能解释了为什么你的内部联接更快(尽管在不知道数据的情况下很难说)。

这里的另一个问题很好地说明了差异:

What is the difference between "INNER JOIN" and "OUTER JOIN"?