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开头的处理顺序,第一个查询应该执行得更好/更快,因为内部查询中只有一条记录,并且会与其他表进行连接。 但是,在执行这两个查询时,我没有发现任何性能差异,并且这两个查询的时间几乎相同。
能否请你检查,让我知道我的想法错了吗?
别担心。的查询的处理分三个阶段发生:
- 解析
- 编译
- 执行
编译阶段的一个关键部分是最优化。这是SQL引擎确定最佳执行计划的时间。
在第一个查询时,SQL Server会忽略子查询。这两个查询应该有相同的执行计划。
注:这是不是在所有的数据库如此。一些更简单的数据库实际上实现了子查询。
从美学的角度来看,我更喜欢第二个查询 - 只是为了避免不必要的子查询,所以所有的过滤都在where
子句的外部(它是预期的地方)。
您的一般前提是SQL的错误方法。
首先编写查询,让你的DB工作了计划。只有在发现问题时才进行优化,否则通常能更好地利用时间。
查询计划会告诉你这是怎么回事。
它与您使用的表的顺序无关。 除非你使用查询提示(FORCE ORDER),我不建议。 无论如何,您正在使用星号(*)取消优化SQL Server执行计划的机会。只使用你真正需要的列。重建统计信息以确保SQL Server具有足够的信息来构建最佳执行计划。
没有“逻辑处理顺序”,除非你的意思是“1评估查询:1的子表达式”,但是这无关紧要,因为DBMS不这样做。你错误的想法是认为你有一个DBMS执行的合理心理模型。阅读关于SQL的声明。关于查询执行/实现 - 整本书都在等待着。只需简单地设计&查询和了解索引&计划和您的DBMS的基本优化模型/策略。
您可以使用'实际执行计划'吗?运行查询之前[Ctrl + M]? – PeterH
如果您查看执行计划,您应该能够看到如何为这两个查询提取数据。 – VDK
查看估计/实际计划。 SQL立即向表中抛出一个谓词值Employees –