Rewrite SQL Subqueries as Outer Joins
Oracle Tips by Burleson Consulting
January 29, 2004
Because SQL is a
declarative language, you can write the same query in many forms, each
getting the same result but with vastly different execution plans and
Also see my related notes on
rewrite an exists subquery using rank and partition analytics.
In this example, we select all books that do not have
any sales. Note that this is a non-correlated sub-query, but it could
be re-written in several ways.
NOT IN (select book_key from sales);
There are serious problems with subqueries that may return NULL values.
It is a good idea to discourage the use of the NOT IN clause (which invokes
a sub-query) and to prefer NOT EXISTS (which invokes a correlated
sub-query), since the query returns no rows if any rows returned by the
sub-query contain null values.
NOT EXISTS (select
book_key from sales s where b.book_key = s.book_key);
Additionally, the MINUS operator can be used to exclude results with
better performance. For instance:
select book_key from book
select book_key from sales;
This query will query BOOK and SALES with the option of using fast full
index or full index scans.
Subqueries can often be re-written to use a standard
outer join, resulting in faster performance. As we may know, an outer join
uses the plus sign (+) operator to tell the database to return all
non-matching rows with NULL values. Hence we combine the outer join with a
NULL test in the WHERE clause to reproduce the result set without using a
b.book_key = s.book_key(+)
s.book_key IS NULL;
This execution plan will also be faster by eliminating
Prior to Oracle10g there was a bug that caused a huge execution
difference between EXISTS and IN. Starting in 10g release 2 and
beyond, Oracle \will automatically rewrite an IN subquery to use the EXISTS
If you like Oracle tuning, see the book "Oracle
Tuning: The Definitive Reference", with 950 pages of tuning tips and
You can buy it direct from the publisher for 30%-off and get
instant access to the code depot of Oracle tuning scripts.