Say, I have the below two tables
------------------------------
| employee |
------------------------------
| employee_id | employee_name |
------------------------------
| 1 | one |
| 2 | two |
| 3 | three |
------------------------------
and
-------------------------------------------
| feedback |
-------------------------------------------
| employee_id (FK) | comments |
-------------------------------------------
| 2 | comment two |
-------------------------------------------
What is the best (in terms of performance) way of retrieving all employees who have not had their feedback given?
I was thinking of the below SQL but because it uses subquery, I am not sure how fast it will be when the number of records in both the tables grow.
SELECT * FROM employee WHERE employee_id NOT IN (SELECT employee_id FROM feedback)
The database is Oracle and all key columns have indexes.
Update
Thanks everybody, I wish I could accept more than one answer! This is what I used in the end (my table structure wasn’t quite as simple as shown here as I had joins with several other tables).
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
You could use:
Which should be pretty good. I assume the EMPLOYEE_ID columns are indexed…
Try it and see what your explain plan looks like.
EDIT: As you have said you do not have the PLAN table then this article from Tom Kyte (Oracle VP) is useful:
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:313616750808
It suggests reasoning behind why each solution (
NOT IN, NOT EXISTS, OUTER JOIN) might be better under circumstances.There is also this from the prolific Don Burleson:
http://www.dba-oracle.com/oracle_tips_subq_rewrite.htm