<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Join Elimination</title>
	<atom:link href="http://antognini.ch/2010/01/join-elimination/feed/" rel="self" type="application/rss+xml" />
	<link>http://antognini.ch/2010/01/join-elimination/</link>
	<description></description>
	<lastBuildDate>Fri, 10 Sep 2010 07:45:48 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Donatello Settembrino</title>
		<link>http://antognini.ch/2010/01/join-elimination/comment-page-1/#comment-8065</link>
		<dc:creator>Donatello Settembrino</dc:creator>
		<pubDate>Mon, 01 Mar 2010 07:19:54 +0000</pubDate>
		<guid isPermaLink="false">http://antognini.ch/?p=826#comment-8065</guid>
		<description>Yes, it was just what I asked and confirm that I wanted

Thanks

Donatello</description>
		<content:encoded><![CDATA[<p>Yes, it was just what I asked and confirm that I wanted</p>
<p>Thanks</p>
<p>Donatello</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Christian Antognini</title>
		<link>http://antognini.ch/2010/01/join-elimination/comment-page-1/#comment-8045</link>
		<dc:creator>Christian Antognini</dc:creator>
		<pubDate>Sun, 28 Feb 2010 15:24:50 +0000</pubDate>
		<guid isPermaLink="false">http://antognini.ch/?p=826#comment-8045</guid>
		<description>Ciao Donatello

&gt; why do not you want to apply the constraints, I believe the following
&gt; solution (PK and FK mode RELY), is the only viable, right?

Sorry, but I&#039;m not sure to understand what do you mean. Hence, if I missed you question, let me know!

In the case do you want to know how to take advantage of join elimination in case of missing (enforced) constraints, yes, AFAIK the trick with the disabled constraints marked with RELY is the only viable option. 

HTH
Chris</description>
		<content:encoded><![CDATA[<p>Ciao Donatello</p>
<p>> why do not you want to apply the constraints, I believe the following<br />
> solution (PK and FK mode RELY), is the only viable, right?</p>
<p>Sorry, but I&#8217;m not sure to understand what do you mean. Hence, if I missed you question, let me know!</p>
<p>In the case do you want to know how to take advantage of join elimination in case of missing (enforced) constraints, yes, AFAIK the trick with the disabled constraints marked with RELY is the only viable option. </p>
<p>HTH<br />
Chris</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Donatello Settembrino</title>
		<link>http://antognini.ch/2010/01/join-elimination/comment-page-1/#comment-7573</link>
		<dc:creator>Donatello Settembrino</dc:creator>
		<pubDate>Fri, 05 Feb 2010 14:17:11 +0000</pubDate>
		<guid isPermaLink="false">http://antognini.ch/?p=826#comment-7573</guid>
		<description>Ciao Christian,
but if the tables are without PK and FK
why do not you want to apply the constraints, I believe the following
solution (PK and FK mode RELY), is the only viable, right?

&lt;pre&gt;
SQL&gt; CREATE TABLE t1 (
  2      id NUMBER NOT NULL,
  3      n NUMBER,
  4      pad VARCHAR2(4000)
  5  );

SQL&gt; insert into t1
  2      select rownum as id, rownum+1 as n, dbms_random.string(&#039;Z&#039;, 1000) as pad 
  3      from dual 
  4      connect by level &lt;= 100000;

SQL&gt; CREATE TABLE t2 (
  2        id NUMBER NOT NULL,
  3        t1_id NUMBER NOT NULL,
  4        n NUMBER,
  5        pad VARCHAR2(4000)
  6  );

SQL&gt; insert into t2
  2      select rownum as id, rownum as t1_id, rownum+1 as n, dbms_random.string(&#039;Z&#039;, 1000) as pad 
  3      from dual 
  4      connect by level &lt;= 100000;

SQL&gt; CREATE VIEW v AS
  2       SELECT t1.id AS t1_id, t1.n AS t1_n, t2.id AS t2_id, t2.n AS t2_n
  3       FROM t1, t2
  4       WHERE t1.id = t2.t1_id;


SQL&gt; ALTER TABLE t1 ADD CONSTRAINT t1_pk
  2      PRIMARY KEY (id)  
  3      RELY DISABLE NOVALIDATE;


SQL&gt; ALTER TABLE t2 ADD CONSTRAINT t2_t1_fk
  2      FOREIGN KEY (t1_id) REFERENCES t1  
  3      RELY DISABLE NOVALIDATE;

SQL&gt; EXPLAIN PLAN FOR SELECT t2_id, t2_n FROM v;


SQL&gt; SELECT * FROM table(dbms_xplan.display(NULL,NULL,&#039;all&#039;));


---------------------------------------------------------------
&#124; Id  &#124; Operation         &#124; Name &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124;
---------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT  &#124;      &#124;   100K&#124;  1464K&#124;  2522   (1)&#124;
&#124;   1 &#124;  TABLE ACCESS FULL&#124; T2   &#124;   100K&#124;  1464K&#124;  2522   (1)&#124;
---------------------------------------------------------------

&lt;/pre&gt;

thanks
Donatello</description>
		<content:encoded><![CDATA[<p>Ciao Christian,<br />
but if the tables are without PK and FK<br />
why do not you want to apply the constraints, I believe the following<br />
solution (PK and FK mode RELY), is the only viable, right?</p>
<p><pre>
SQL&gt; CREATE TABLE t1 (
  2      id NUMBER NOT NULL,
  3      n NUMBER,
  4      pad VARCHAR2(4000)
  5  );

SQL&gt; insert into t1
  2      select rownum as id, rownum+1 as n, dbms_random.string(&#039;Z&#039;, 1000) as pad 
  3      from dual 
  4      connect by level &lt;= 100000;

SQL&gt; CREATE TABLE t2 (
  2        id NUMBER NOT NULL,
  3        t1_id NUMBER NOT NULL,
  4        n NUMBER,
  5        pad VARCHAR2(4000)
  6  );

SQL&gt; insert into t2
  2      select rownum as id, rownum as t1_id, rownum+1 as n, dbms_random.string(&#039;Z&#039;, 1000) as pad 
  3      from dual 
  4      connect by level &lt;= 100000;

SQL&gt; CREATE VIEW v AS
  2       SELECT t1.id AS t1_id, t1.n AS t1_n, t2.id AS t2_id, t2.n AS t2_n
  3       FROM t1, t2
  4       WHERE t1.id = t2.t1_id;

SQL&gt; ALTER TABLE t1 ADD CONSTRAINT t1_pk
  2      PRIMARY KEY (id)  
  3      RELY DISABLE NOVALIDATE;

SQL&gt; ALTER TABLE t2 ADD CONSTRAINT t2_t1_fk
  2      FOREIGN KEY (t1_id) REFERENCES t1  
  3      RELY DISABLE NOVALIDATE;

SQL&gt; EXPLAIN PLAN FOR SELECT t2_id, t2_n FROM v;

SQL&gt; SELECT * FROM table(dbms_xplan.display(NULL,NULL,&#039;all&#039;));

---------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)|
---------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |   100K|  1464K|  2522   (1)|
|   1 |  TABLE ACCESS FULL| T2   |   100K|  1464K|  2522   (1)|
---------------------------------------------------------------

</pre></p>
<p>thanks<br />
Donatello</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Blogroll Report 08/01/2009 – 15/01/2010 &#171; Coskan&#8217;s Approach to Oracle</title>
		<link>http://antognini.ch/2010/01/join-elimination/comment-page-1/#comment-7490</link>
		<dc:creator>Blogroll Report 08/01/2009 – 15/01/2010 &#171; Coskan&#8217;s Approach to Oracle</dc:creator>
		<pubDate>Tue, 02 Feb 2010 18:58:11 +0000</pubDate>
		<guid isPermaLink="false">http://antognini.ch/?p=826#comment-7490</guid>
		<description>[...] 12-How does Join Elimination works in 11G for unnecessary self joins? Christian Antognini-Join Elimination [...]</description>
		<content:encoded><![CDATA[<p>[...] 12-How does Join Elimination works in 11G for unnecessary self joins? Christian Antognini-Join Elimination [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Christian Antognini</title>
		<link>http://antognini.ch/2010/01/join-elimination/comment-page-1/#comment-7313</link>
		<dc:creator>Christian Antognini</dc:creator>
		<pubDate>Mon, 25 Jan 2010 16:45:10 +0000</pubDate>
		<guid isPermaLink="false">http://antognini.ch/?p=826#comment-7313</guid>
		<description>Hi

@Sake

&gt; However, I’m curious, in what kind of real world situation when the “unnecessary” self-joins will occur ?

I do not have a real case to share with you. But, let&#039;s face it, lot of databases run &quot;strange&quot; SQL statements ;-)


@Gary

&gt; The optimized selects assume the constraint is in force and give a one row result based solely on t2.

That should not happen. IMO this is a bug.


@Dongkyu

First of all, thank you for the detailed feedback! BTW, I do not consider case 7 a &quot;join elimination&quot; technique. And that even though a join is avoided. Otherwise we should consider also query rewrite techinques being part of &quot;join elimination&quot;. Anyway, it&#039;s not really important ;-)


@Timur

&gt; the second case is an enhancement introduced in a one-off patch #7679164 for most *nix

Thanks for the information. I didn&#039;t know it...


Cheers,
Chris</description>
		<content:encoded><![CDATA[<p>Hi</p>
<p>@Sake</p>
<p>> However, I’m curious, in what kind of real world situation when the “unnecessary” self-joins will occur ?</p>
<p>I do not have a real case to share with you. But, let&#8217;s face it, lot of databases run &#8220;strange&#8221; SQL statements ;-)</p>
<p>@Gary</p>
<p>> The optimized selects assume the constraint is in force and give a one row result based solely on t2.</p>
<p>That should not happen. IMO this is a bug.</p>
<p>@Dongkyu</p>
<p>First of all, thank you for the detailed feedback! BTW, I do not consider case 7 a &#8220;join elimination&#8221; technique. And that even though a join is avoided. Otherwise we should consider also query rewrite techinques being part of &#8220;join elimination&#8221;. Anyway, it&#8217;s not really important ;-)</p>
<p>@Timur</p>
<p>> the second case is an enhancement introduced in a one-off patch #7679164 for most *nix</p>
<p>Thanks for the information. I didn&#8217;t know it&#8230;</p>
<p>Cheers,<br />
Chris</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Log Buffer #175: a Carnival of the Vanities for DBAs &#124; The Pythian Blog</title>
		<link>http://antognini.ch/2010/01/join-elimination/comment-page-1/#comment-7137</link>
		<dc:creator>Log Buffer #175: a Carnival of the Vanities for DBAs &#124; The Pythian Blog</dc:creator>
		<pubDate>Fri, 15 Jan 2010 18:34:11 +0000</pubDate>
		<guid isPermaLink="false">http://antognini.ch/?p=826#comment-7137</guid>
		<description>[...] are still Striving for Optimal Performance, like Christian Antognini is. Here&#8217;s his item on join elimination, which he introduces thus: &#8220;In some specific situations the query optimizer is able to [...]</description>
		<content:encoded><![CDATA[<p>[...] are still Striving for Optimal Performance, like Christian Antognini is. Here&#8217;s his item on join elimination, which he introduces thus: &#8220;In some specific situations the query optimizer is able to [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Gary</title>
		<link>http://antognini.ch/2010/01/join-elimination/comment-page-1/#comment-7052</link>
		<dc:creator>Gary</dc:creator>
		<pubDate>Thu, 14 Jan 2010 23:11:26 +0000</pubDate>
		<guid isPermaLink="false">http://antognini.ch/?p=826#comment-7052</guid>
		<description>@sake. One real-world example for case 1 is where you use a view to join a parent and child and the view has columns from both tables. If, when the view is used, only columns from the child table are used the join to the parent can be omitted.</description>
		<content:encoded><![CDATA[<p>@sake. One real-world example for case 1 is where you use a view to join a parent and child and the view has columns from both tables. If, when the view is used, only columns from the child table are used the join to the parent can be omitted.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Timur Akhmadeev</title>
		<link>http://antognini.ch/2010/01/join-elimination/comment-page-1/#comment-6979</link>
		<dc:creator>Timur Akhmadeev</dc:creator>
		<pubDate>Tue, 12 Jan 2010 07:57:23 +0000</pubDate>
		<guid isPermaLink="false">http://antognini.ch/?p=826#comment-6979</guid>
		<description>Hi Christian,

the second case is an enhancement introduced in a one-off patch #7679164 for most *nix, and is included in Win patch bundle #19</description>
		<content:encoded><![CDATA[<p>Hi Christian,</p>
<p>the second case is an enhancement introduced in a one-off patch #7679164 for most *nix, and is included in Win patch bundle #19</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: extremedb</title>
		<link>http://antognini.ch/2010/01/join-elimination/comment-page-1/#comment-6976</link>
		<dc:creator>extremedb</dc:creator>
		<pubDate>Tue, 12 Jan 2010 06:08:33 +0000</pubDate>
		<guid isPermaLink="false">http://antognini.ch/?p=826#comment-6976</guid>
		<description>hi Christian

I found 7 Rules for Join Elimination in last year

1.Primary Key-Foreign Key - normal join, Starting in 10gR2
2.Primary Key-Foreign Key - ANSI  join, Starting in 11gR1
3.Primary Key-Foreign Key - (semi/anti) join, Starting in 11gR1
4.Unique Index            - outer join, Starting in 11gR1

Every guru knows above 4 things

5.Primary Key-Primary Key - simple self join, Starting in 11gR2 
--&gt; you &#039;ve aleady mentioned  

There are two more things and one simular thing
6.Primary Key-Primary Key - self join filter subsumption, Starting in 11gR2 
7.Join Back Elimination - Using Bit Map Join Index, Starting in 9iR1

let me show you two things

6.Primary Key-Primary Key - self join filter subsumption
ex)
SELECT e1.employee_id, e1.salary, e1.manager_id
  FROM employee e1
 WHERE e1.salary &gt; 10000
   AND e1.manager_id &gt; 100
   AND e1.employee_id IN (SELECT e2.employee_id
                            FROM employee e2
                           WHERE e2.salary &gt; 9000);
                           
Outline Data:
    /*+
      …omission
      ELIMINATE_JOIN(@&quot;SEL$5DA710D3&quot; &quot;E1&quot;@&quot;SEL$1&quot;)
      …omission
   */
                                                
*************************
Join Elimination (JE)    
*************************
…omission
JE:   eliminate table: EMPLOYEE (E1)
JE:   Replaced column: E1.MANAGER_ID with column: E2.MANAGER_ID
JE:   Replaced column: E1.SALARY with column: E2.SALARY
JE:   Replaced column: E1.EMPLOYEE_ID with column: E2.EMPLOYEE_ID
JE:   Replaced column: E1.SALARY with column: E2.SALARY
JE:   Replaced column: E1.MANAGER_ID with column: E2.MANAGER_ID
Registered qb: SEL$CAE83587 0x88a90ea8 (JOIN REMOVED FROM QUERY BLOCK SEL$5DA710D3; SEL$5DA710D3; &quot;E1&quot;@&quot;SEL$1&quot;)


7.Join Back Elimination - Using Bit Map Join Index
ex)

CREATE BITMAP INDEX emp_join_idx_01 ON employee(d.location_id)
 FROM employee e, department d
WHERE e.department_id = d.department_id;

SELECT /*+ INDEX(e emp_join_idx_01) */
       COUNT (*)
  FROM employee e, department d
 WHERE e.department_id = d.department_id 
   AND d.location_id = 1700;


------------------------------------------------------+
&#124; Id  &#124; Operation                    &#124; Name           &#124;
------------------------------------------------------+
&#124; 0   &#124; SELECT STATEMENT             &#124;                &#124;
&#124; 1   &#124;  SORT AGGREGATE              &#124;                &#124;
&#124; 2   &#124;   BITMAP CONVERSION COUNT    &#124;                &#124;
&#124; 3   &#124;    BITMAP INDEX SINGLE VALUE &#124; EMP_JOIN_IDX_01&#124;
------------------------------------------------------+

Outline Data:
  /*+
      …omission
      ELIMINATE_JOIN(@&quot;SEL$1&quot; &quot;D&quot;@&quot;SEL$1&quot;)
      Outline(@&quot;SEL$1&quot;)
      BITMAP_TREE(@&quot;SEL$1&quot; &quot;E&quot;@&quot;SEL$1&quot; AND((&quot;DEPARTMENT&quot;.&quot;LOCATION_ID&quot;)))
      …omission
  */

***************************************
STAR TRANSFORMATION PLANS
***************************************
Best join order so far: 2
  Marked for join-back elimination: &quot;D&quot;@&quot;SEL$1&quot;
Join order[1]:  EMPLOYEE[E]#0
***********************
Best so far:  Table#: 0  cost: 1.0003  card: 15.2857  bytes: 45
***********************
Registered qb: SEL$DBFB62D6 0xe414820 (BITMAP JOIN INDEX JOINBACK ELIMINATION SEL$1; SEL$1; &quot;D&quot;@&quot;SEL$1&quot;)



Last, One simulat thing
be careful, It is not join-elimination
It is called Subquery Coalescing, Starting in 11gR2 
ex) 
SELECT /*+ QB_NAME(MAIN) */ e.employee_id, e.first_name, e.last_name
  FROM employee e
 WHERE e.salary &gt; 2000
   AND (   EXISTS (SELECT /*+ QB_NAME(SUB1) */ 1
                     FROM department d1
                    WHERE d1.department_id = e.department_id
                      AND d1.location_id = 1700)
        OR EXISTS (SELECT /*+ QB_NAME(SUB2) */ 1
                     FROM department d2
                    WHERE d2.department_id = e.department_id
                      AND d2.department_name &gt; &#039;Accounting&#039;)
       ) ;
 

---------------------------------------------------+
&#124; Id  &#124; Operation                      &#124; Name      &#124;
---------------------------------------------------+
&#124; 0   &#124; SELECT STATEMENT               &#124;           &#124;
&#124; 1   &#124;  MERGE JOIN                    &#124;           &#124;
&#124; 2   &#124;   SORT UNIQUE                  &#124;           &#124;
&#124; 3   &#124;    TABLE ACCESS BY INDEX ROWID &#124; DEPARTMENT&#124;
&#124; 4   &#124;     INDEX FULL SCAN            &#124; DEPT_ID_PK&#124;
&#124; 5   &#124;   SORT JOIN                    &#124;           &#124;
&#124; 6   &#124;    TABLE ACCESS FULL           &#124; EMPLOYEE  &#124;
---------------------------------------------------+


Outline Data:
  /*+
      …omission
      COALESCE_SQ(@&quot;SUB2&quot;)
      Outline(@&quot;SEL$4B4BED4E&quot;)
      COALESCE_SQ(@&quot;SUB1&quot;)      
      …omission
  */
             
Subquery Coalescing rewite SQL LIKE below.

SELECT /*+ QB_NAME(MAIN) */ e.employee_id, e.first_name, e.last_name
  FROM employee e
 WHERE e.salary &gt; 2000
   AND EXISTS (SELECT /*+ QB_NAME(SUB1) */ 1
                 FROM department d1
                WHERE d1.department_id = e.department_id
                  AND (d1.location_id = 1700 OR d2.department_name &gt; &#039;Accounting&#039;)) ;

from 10053 trace

Registered qb: SEL$4B4BED4E 0x2428950 (SUBQUERY COALESCE SUB1; SUB1)
---------------------
QUERY BLOCK SIGNATURE
---------------------
  signature (): QB_NAME=SEL$4B4BED4E nbfros=1 flg=0
    fro(0): flg=0 objn=73948 hint_alias=&quot;D1&quot;@&quot;SUB1&quot;

Registered qb: SEL$5DD85A06 0x2428950 (SUBQUERY COALESCE SEL$4B4BED4E; SUB2)
---------------------
QUERY BLOCK SIGNATURE
---------------------
  signature (): QB_NAME=SEL$5DD85A06 nbfros=1 flg=0
    fro(0): flg=0 objn=73948 hint_alias=&quot;D1&quot;@&quot;SUB1&quot;

good stuff. right?
</description>
		<content:encoded><![CDATA[<p>hi Christian</p>
<p>I found 7 Rules for Join Elimination in last year</p>
<p>1.Primary Key-Foreign Key &#8211; normal join, Starting in 10gR2<br />
2.Primary Key-Foreign Key &#8211; ANSI  join, Starting in 11gR1<br />
3.Primary Key-Foreign Key &#8211; (semi/anti) join, Starting in 11gR1<br />
4.Unique Index            &#8211; outer join, Starting in 11gR1</p>
<p>Every guru knows above 4 things</p>
<p>5.Primary Key-Primary Key &#8211; simple self join, Starting in 11gR2<br />
&#8211;&gt; you &#8216;ve aleady mentioned  </p>
<p>There are two more things and one simular thing<br />
6.Primary Key-Primary Key &#8211; self join filter subsumption, Starting in 11gR2<br />
7.Join Back Elimination &#8211; Using Bit Map Join Index, Starting in 9iR1</p>
<p>let me show you two things</p>
<p>6.Primary Key-Primary Key &#8211; self join filter subsumption<br />
ex)<br />
SELECT e1.employee_id, e1.salary, e1.manager_id<br />
  FROM employee e1<br />
 WHERE e1.salary &gt; 10000<br />
   AND e1.manager_id &gt; 100<br />
   AND e1.employee_id IN (SELECT e2.employee_id<br />
                            FROM employee e2<br />
                           WHERE e2.salary &gt; 9000);</p>
<p>Outline Data:<br />
    /*+<br />
      …omission<br />
      ELIMINATE_JOIN(@&#8221;SEL$5DA710D3&#8243; &#8220;E1&#8243;@&#8221;SEL$1&#8243;)<br />
      …omission<br />
   */</p>
<p>*************************<br />
Join Elimination (JE)<br />
*************************<br />
…omission<br />
JE:   eliminate table: EMPLOYEE (E1)<br />
JE:   Replaced column: E1.MANAGER_ID with column: E2.MANAGER_ID<br />
JE:   Replaced column: E1.SALARY with column: E2.SALARY<br />
JE:   Replaced column: E1.EMPLOYEE_ID with column: E2.EMPLOYEE_ID<br />
JE:   Replaced column: E1.SALARY with column: E2.SALARY<br />
JE:   Replaced column: E1.MANAGER_ID with column: E2.MANAGER_ID<br />
Registered qb: SEL$CAE83587 0&#215;88a90ea8 (JOIN REMOVED FROM QUERY BLOCK SEL$5DA710D3; SEL$5DA710D3; &#8220;E1&#8243;@&#8221;SEL$1&#8243;)</p>
<p>7.Join Back Elimination &#8211; Using Bit Map Join Index<br />
ex)</p>
<p>CREATE BITMAP INDEX emp_join_idx_01 ON employee(d.location_id)<br />
 FROM employee e, department d<br />
WHERE e.department_id = d.department_id;</p>
<p>SELECT /*+ INDEX(e emp_join_idx_01) */<br />
       COUNT (*)<br />
  FROM employee e, department d<br />
 WHERE e.department_id = d.department_id<br />
   AND d.location_id = 1700;</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+<br />
| Id  | Operation                    | Name           |<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+<br />
| 0   | SELECT STATEMENT             |                |<br />
| 1   |  SORT AGGREGATE              |                |<br />
| 2   |   BITMAP CONVERSION COUNT    |                |<br />
| 3   |    BITMAP INDEX SINGLE VALUE | EMP_JOIN_IDX_01|<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+</p>
<p>Outline Data:<br />
  /*+<br />
      …omission<br />
      ELIMINATE_JOIN(@&#8221;SEL$1&#8243; &#8220;D&#8221;@&#8221;SEL$1&#8243;)<br />
      Outline(@&#8221;SEL$1&#8243;)<br />
      BITMAP_TREE(@&#8221;SEL$1&#8243; &#8220;E&#8221;@&#8221;SEL$1&#8243; AND((&#8220;DEPARTMENT&#8221;.&#8221;LOCATION_ID&#8221;)))<br />
      …omission<br />
  */</p>
<p>***************************************<br />
STAR TRANSFORMATION PLANS<br />
***************************************<br />
Best join order so far: 2<br />
  Marked for join-back elimination: &#8220;D&#8221;@&#8221;SEL$1&#8243;<br />
Join order[1]:  EMPLOYEE[E]#0<br />
***********************<br />
Best so far:  Table#: 0  cost: 1.0003  card: 15.2857  bytes: 45<br />
***********************<br />
Registered qb: SEL$DBFB62D6 0xe414820 (BITMAP JOIN INDEX JOINBACK ELIMINATION SEL$1; SEL$1; &#8220;D&#8221;@&#8221;SEL$1&#8243;)</p>
<p>Last, One simulat thing<br />
be careful, It is not join-elimination<br />
It is called Subquery Coalescing, Starting in 11gR2<br />
ex)<br />
SELECT /*+ QB_NAME(MAIN) */ e.employee_id, e.first_name, e.last_name<br />
  FROM employee e<br />
 WHERE e.salary &gt; 2000<br />
   AND (   EXISTS (SELECT /*+ QB_NAME(SUB1) */ 1<br />
                     FROM department d1<br />
                    WHERE d1.department_id = e.department_id<br />
                      AND d1.location_id = 1700)<br />
        OR EXISTS (SELECT /*+ QB_NAME(SUB2) */ 1<br />
                     FROM department d2<br />
                    WHERE d2.department_id = e.department_id<br />
                      AND d2.department_name &gt; &#8216;Accounting&#8217;)<br />
       ) ;</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+<br />
| Id  | Operation                      | Name      |<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+<br />
| 0   | SELECT STATEMENT               |           |<br />
| 1   |  MERGE JOIN                    |           |<br />
| 2   |   SORT UNIQUE                  |           |<br />
| 3   |    TABLE ACCESS BY INDEX ROWID | DEPARTMENT|<br />
| 4   |     INDEX FULL SCAN            | DEPT_ID_PK|<br />
| 5   |   SORT JOIN                    |           |<br />
| 6   |    TABLE ACCESS FULL           | EMPLOYEE  |<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+</p>
<p>Outline Data:<br />
  /*+<br />
      …omission<br />
      COALESCE_SQ(@&#8221;SUB2&#8243;)<br />
      Outline(@&#8221;SEL$4B4BED4E&#8221;)<br />
      COALESCE_SQ(@&#8221;SUB1&#8243;)<br />
      …omission<br />
  */</p>
<p>Subquery Coalescing rewite SQL LIKE below.</p>
<p>SELECT /*+ QB_NAME(MAIN) */ e.employee_id, e.first_name, e.last_name<br />
  FROM employee e<br />
 WHERE e.salary &gt; 2000<br />
   AND EXISTS (SELECT /*+ QB_NAME(SUB1) */ 1<br />
                 FROM department d1<br />
                WHERE d1.department_id = e.department_id<br />
                  AND (d1.location_id = 1700 OR d2.department_name &gt; &#8216;Accounting&#8217;)) ;</p>
<p>from 10053 trace</p>
<p>Registered qb: SEL$4B4BED4E 0&#215;2428950 (SUBQUERY COALESCE SUB1; SUB1)<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
QUERY BLOCK SIGNATURE<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
  signature (): QB_NAME=SEL$4B4BED4E nbfros=1 flg=0<br />
    fro(0): flg=0 objn=73948 hint_alias=&#8221;D1&#8243;@&#8221;SUB1&#8243;</p>
<p>Registered qb: SEL$5DD85A06 0&#215;2428950 (SUBQUERY COALESCE SEL$4B4BED4E; SUB2)<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
QUERY BLOCK SIGNATURE<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
  signature (): QB_NAME=SEL$5DD85A06 nbfros=1 flg=0<br />
    fro(0): flg=0 objn=73948 hint_alias=&#8221;D1&#8243;@&#8221;SUB1&#8243;</p>
<p>good stuff. right?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: sake</title>
		<link>http://antognini.ch/2010/01/join-elimination/comment-page-1/#comment-6971</link>
		<dc:creator>sake</dc:creator>
		<pubDate>Tue, 12 Jan 2010 01:56:01 +0000</pubDate>
		<guid isPermaLink="false">http://antognini.ch/?p=826#comment-6971</guid>
		<description>Very useful tip. Thanks.

However, I&#039;m curious, in what kind of real world situation when the “unnecessary” self-joins will occur ?
(Besides coder mistake, of course)</description>
		<content:encoded><![CDATA[<p>Very useful tip. Thanks.</p>
<p>However, I&#8217;m curious, in what kind of real world situation when the “unnecessary” self-joins will occur ?<br />
(Besides coder mistake, of course)</p>
]]></content:encoded>
	</item>
</channel>
</rss>
