2

我有三个表,即员工、部门和申诉。雇员表有超过一百万条记录。我需要找到员工的详细信息,他/她的部门以及他/她提出的申诉。

我可以想到以下两个查询来找到结果:

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);

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

你能检查一下,让我知道我在哪里想错了吗?

4

4 回答 4

4

别担心。查询的处理分三个阶段进行:

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

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

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

注意:并非所有数据库都如此。一些更简单的数据库实际上实现了子查询。

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

于 2017-10-13T10:19:48.263 回答
1

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

首先编写查询,让您的数据库制定计划。仅当您发现问题时才进行优化,否则您通常能够更好地利用您的时间。

查询计划会告诉你发生了什么。

于 2017-10-13T10:22:42.717 回答
0

您使用的表格的顺序无关紧要。除非您使用我不推荐的查询提示(FORCE ORDER)。无论如何,您正在利用星号 (*) 来优化 SQL Server 的执行计划。仅使用您真正需要的列。重建统计信息以确保 SQL Server 有足够的信息来构建最佳执行计划。

于 2017-10-13T10:56:08.607 回答
0

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

哪个查询性能更高?

于 2017-10-13T20:53:54.567 回答