使用子查询的性能注意事项

时间:2012-01-11 15:07:05

标签: sql oracle subquery

说,我有以下两个表

 ------------------------------
|           employee           |
 ------------------------------
| employee_id  | employee_name |  
 ------------------------------
|     1        |     one       |
|     2        |     two       |
|     3        |     three     |
 ------------------------------

 -------------------------------------------
|                feedback                   |
 -------------------------------------------
| employee_id (FK)  |       comments        |  
 -------------------------------------------
|         2         |     comment two       |
 -------------------------------------------

检索没有给出反馈的所有员工的最佳(在绩效方面)方法是什么?

我在考虑下面的SQL,但因为它使用了子查询,所以我不确定当两个表中的记录数量增长时会有多快。

SELECT * FROM employee WHERE employee_id NOT IN (SELECT employee_id FROM feedback)

数据库是Oracle,所有键列都有索引。

更新

谢谢大家,我希望我能接受不止一个答案!这就是我最后使用的内容(我的表格结构并不像这里显示的那样简单,因为我加入了其他几个表格。)

SELECT 
    e.name, m.name, a.postcode 
FROM 
    employee LEFT OUTER JOIN feedback f on (e.employee_id = f.employee_id),
    address a, manager m 
WHERE a.address_id = e.address_id
AND m.manager_id = e.manager_id
AND f.employee_id IS NULL

4 个答案:

答案 0 :(得分:4)

您可以使用:

SELECT e.* 
  FROM employee e 
  LEFT OUTER JOIN feedback f ON (e.employee_id = f.employee_id)
 WHERE f.employee_id IS NULL 

哪个应该不错。我假设EMPLOYEE_ID列已编入索引......

试一试,看看你的解释计划是什么样的。

编辑:正如您所说的那样,您没有PLAN表,那么来自Tom Kyte(Oracle VP)的这篇文章很有用: http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:313616750808

它建议推理为什么每个解决方案(NOT IN, NOT EXISTS, OUTER JOIN)在某些情况下可能会更好。

来自多产的Don Burleson还有这个: http://www.dba-oracle.com/oracle_tips_subq_rewrite.htm

答案 1 :(得分:2)

可能:

SELECT e.* FROM EMPLOYEE e
LEFT OUTER JOIN FEEDBACK f ON e.EMPLOYEE_ID = f.EMPLOYEE_ID
WHERE f.EMPLOYEE_ID IS NULL

但你可以阅读THIS有关它的文章!

答案 2 :(得分:2)

尝试使用不同的查询并比较他们的计划。 实现您的查询的另一种可能性:

select EMPLOYEE_ID from employee
MINUS
select EMPLOYEE_ID from FEEDBACK

答案 3 :(得分:2)

最好的方法是尝试使用相关数据的每种方法 - 我建议使用not exists

select * from EMPLOYEE e 
where not exists
(select null from FEEDBACK f where e.EMPLOYEE_ID = f.EMPLOYEE_ID)