SQL性能:先过滤或先联系

问题描述:

我有三个表,即员工,部门和申诉。 Employees表有超过一百万条记录。我需要找到员工的细节,他/她的部门和他/她提出的不满。SQL性能:先过滤或先联系

我能想到下面两个查询找到了结果:

1.过滤记录第一个获得其数据时,要求员工只记录:

SELECT * FROM (SELECT * FROM Employees WHERE EmployeeID= @EmployeeID) Emp  
LEFT JOIN Department Dpt ON Emp.EmployeeID= Dpt.EmployeeID  
LEFT JOIN Grievance Grv ON Emp.EmployeeID= Grv.EmployeeID; 

2.加入第一个:

SELECT * FROM Employees Emp  
    LEFT JOIN Department Dpt ON Emp.EmployeeID= Dpt.EmployeeID  
    LEFT JOIN Grievance Grv ON Emp.EmployeeID= Grv.EmployeeID  
WHERE EmployeeID= @EmployeeID); 

如果我们考虑SQL逻辑p以FROM> INNER JOIN> OUTER JOIN> WHERE> .... SELECT开头的处理顺序,第一个查询应该执行得更好/更快,因为内部查询中只有一条记录,并且会与其他表进行连接。 但是,在执行这两个查询时,我没有发现任何性能差异,并且这两个查询的时间几乎相同。

能否请你检查,让我知道我的想法错了吗?

+1

您可以使用'实际执行计划'吗?运行查询之前[Ctrl + M]? – PeterH

+1

如果您查看执行计划,您应该能够看到如何为这两个查询提取数据。 – VDK

+1

查看估计/实际计划。 SQL立即向表中抛出一个谓词值Employees –

别担心。的查询的处理分三个阶段发生:

  1. 解析
  2. 编译
  3. 执行

编译阶段的一个关键部分是最优化。这是SQL引擎确定最佳执行计划的时间。

在第一个查询时,SQL Server会忽略子查询。这两个查询应该有相同的执行计划。

注:这是不是在所有的数据库如此。一些更简单的数据库实际上实现了子查询。

从美学的角度来看,我更喜欢第二个查询 - 只是为了避免不必要的子查询,所以所有的过滤都在where子句的外部(它是预期的地方)。

您的一般前提是SQL的错误方法。

首先编写查询,让你的DB工作了计划。只有在发现问题时才进行优化,否则通常能更好地利用时间。

查询计划会告诉你这是怎么回事。

它与您使用的表的顺序无关。 除非你使用查询提示(FORCE ORDER),我不建议。 无论如何,您正在使用星号(*)取消优化SQL Server执行计划的机会。只使用你真正需要的列。重建统计信息以确保SQL Server具有足够的信息来构建最佳执行计划。

没有“逻辑处理顺序”,除非你的意思是“1评估查询:1的子表达式”,但是这无关紧要,因为DBMS不这样做。你错误的想法是认为你有一个DBMS执行的合理心理模型。阅读关于SQL的声明。关于查询执行/实现 - 整本书都在等待着。只需简单地设计&查询和了解索引&计划和您的DBMS的基本优化模型/策略。

Which query is more performant?