Oracle FAQ Your Portal to the Oracle Knowledge Grid
HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US
 

Home -> Community -> Mailing Lists -> Oracle-L -> Re: Optimization of Partitioned Outer Joins

Re: Optimization of Partitioned Outer Joins

From: jaromir nemec <jaromir_at_db-nemec.com>
Date: Mon, 3 Jan 2005 02:02:17 +0100
Message-ID: <003301c4f12f$e014c130$3c02a8c0@JARAWIN>


Hi Christian,

> i.e. to me it seams that the partitioned outer join prevents the CBO to
use the join predicate as access predicate!

exact and in my opinion correct. Otherwise you can get a different result of the query as illustrated in a very simplified version of your query below.

The critical point is see definition of query_partition_clause

http://download-west.oracle.com/docs/cd/B14117_01/server.101/b10759/statements_10002.htm#i2197413

<quote>

The result of a partitioned outer join is a UNION of the outer joins of each of the partitions in the partitioned result set and the table on the other side of the join.

</quote>

My interpretation is, that the partitions are build first, followed by the join.

Note, that in my example the required channel_id = 9 doesn't exist in the constrained time (time_id =1) but is returned in the first query. The second query, that constraint the sales table on time_id = 1 return no data.

I thing this is a very interesting point which makes partitioned outer join on big fact tables more dangerous and I agree that the "native" explanation: first constraint the fact table than build the partitions, would be more straightforward.

It will be interesting to see the ANSI definition of partitioned outer join.

Another minor point is the where clause (WHERE channel_id =9). In my opinion, if the channel_id is known (and only one), there is no need to perform partitioned join.

regards

Jaromir D.B. Nemec

SQL> create table sales

  2 (channel_id number,

  3 time_id number,

  4 amount_sold number);

Table created.

SQL> -- SQL> create table times

  2 (time_id number);

Table created.

SQL> --- SQL> insert into times

  2 select rownum time_id from dba_objects where rownum < 3;

2 rows created.

SQL> -- SQL> insert into sales values (1,1,1);

1 row created.

SQL> insert into sales values (9,2,1);

1 row created.

SQL> commit;

Commit complete.

SQL> -- SQL> SELECT *   2 FROM sales s PARTITION BY (channel_id)

  3 RIGHT OUTER JOIN (

  4                 SELECT time_id

  5                 FROM times t

  6                 WHERE t.time_id = 1

  7               ) t USING (time_id)

  8 WHERE channel_id = 9

  9 ;

CHANNEL_ID TIME_ID AMOUNT_SOLD

         9 1

SQL> SELECT *   2 FROM sales s PARTITION BY (channel_id)

  3 RIGHT OUTER JOIN (

  4                 SELECT time_id

  5                 FROM times t

  6                 WHERE t.time_id = 1

  7               ) t on (s.time_id = s.time_id)

  8 WHERE channel_id = 9 and

  9 s.time_id = 1

 10 ;

no rows selected

SQL>

--
http://www.freelists.org/webpage/oracle-l
Received on Sun Jan 02 2005 - 19:01:41 CST

Original text of this message

HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US