views:

40

answers:

2

Say you've got the following query on 9i:

SELECT /*+ USE_HASH(t2 t3) */
* FROM
table1 t1    -- this has lots of rows
LEFT JOIN table2 t2 ON t1.col1 = t2.col1
    AND t1.col2 = t2.col2
LEFT JOIN table3 t3 ON t1.col1 = t3.col1
    AND t1.col2 = t3.col2

Due to 9i not having RIGHT OUTER HASH JOIN, it needs to hash table1 for both joins. Does it re-hash table1 between joining t2 and t3 (even though it's using the same join columns), or does it keep the same hash information for both joins?

+1  A: 

Look at the plan, it'll tell you the answer.

An example might be something like (I've just made this up):

SELECT
  HASH JOIN
    HASH JOIN
      TABLE FULL SCAN table1
      TABLE FULL SCAN table2
  TABLE FULL SCAN table3

This sample plan involves a scan through table1, hashing its contents as it goes; scans through table2, hashes the results of the join into a second hash, then finally scans table3.

There are other plans it could choose from.

If table1 is the biggest table, and the optimizer knows this (due to stats), it probably won't drive from it though.

Jeffrey Kemp
It's whether oracle optimizes the two hash joins to re-use the hash table (as it's on the same keys) that I was asking about
thecoop
It's an interesting idea but I haven't heard of any optimization for the cbo (proposed or implemented) that would re-use a hash area for a join like this - I'm not even sure it's even feasible, since it would end up with two result sets (t1+t2 and t1+t3) that would then need to be merge joined.
Jeffrey Kemp
+2  A: 

It would need to rehash since the second hash would be table3 against the join of table1/table2 rather than against table1. Or vice versa.

For example, say TABLE1 had 100 rows, table2 had 50 and table3 had 10. Joining table1 to table2 may give 500 rows. It then joins that result set to table3 to give (perhaps) 700 rows.

It won't do a join of table1 to table2, then a join of table1 to table3, then a join of those two intermediate results.

Gary