Re: Unbelievable Outer Join

From: Jonathan Lewis <>
Date: Wed, 12 Aug 2009 22:22:06 +0100
Message-ID: <>

"Jan" <> wrote in message
> Hi,
> our - 64bit EE running on Windows Server 2003 executes one
> kind of insert from select whose explain plan I can't comprehend.
> See the NESTED LOOPS OUTER between TT203_10100000001372631 and
> TI238_14935572?
> The join is written this way:
> TT203_10100000001372631.OID = TI238_14935572.T203VALUE_OID (+)
> Inner table TT203_10100000001372631 has really 6798 rows and outer
> table TI238_14935572 has one. Why would optimizer think this will
> result in 1 row????
> Do you have any experience with this behavior?

It's done that way because it's the right way to do it.

TT203_10100000001372631.OID = TI238_14935572.T203VALUE_OID (+)

|  7 | NESTED LOOPS OUTER           |
|* 8 |  TABLE ACCESS FULL           | TT203_10100000001372631
|* 9 |  TABLE ACCESS BY INDEX ROWID | TI238_14935572
|*10 |   INDEX RANGE SCAN           | I_T201_14935572

The "preserved" table must come first in the join order if you are using a nested loop join. Your syntax is saying:

    report the row from TT203 and matching rows from TI238,     even if there are no rows from TI238

Consequently, for each row in TT203 you must try to find rows from TI238 - hence the plan.

Since you are on 10.2 you have the option for forcing a right outer hash join if you want to reverse the apparent order of execution - but this may not help.

The "1" in line 9 is "one row for each row from line 8", not "one row in total".


Jonathan Lewis

Author: Cost Based Oracle: Fundamentals

The Co-operative Oracle Users' FAQ
Received on Wed Aug 12 2009 - 16:22:06 CDT

Original text of this message