<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
		>
<channel>
	<title>Comments on: Invalid Hints are Silently Ignored? An Invalid USE_HASH Hint Transforms a Sort-Merge Join into a Nested Loops Join</title>
	<atom:link href="http://hoopercharles.wordpress.com/2011/09/30/invalid-hints-are-silently-ignored-an-invalid-use_hash-hint-transforms-a-sort-merge-join-into-a-nested-loops-join/feed/" rel="self" type="application/rss+xml" />
	<link>http://hoopercharles.wordpress.com/2011/09/30/invalid-hints-are-silently-ignored-an-invalid-use_hash-hint-transforms-a-sort-merge-join-into-a-nested-loops-join/</link>
	<description>Miscellaneous Random Oracle Topics: Stop, Think, ... Understand</description>
	<lastBuildDate>Thu, 23 May 2013 04:02:42 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
	<item>
		<title>By: Charles Hooper</title>
		<link>http://hoopercharles.wordpress.com/2011/09/30/invalid-hints-are-silently-ignored-an-invalid-use_hash-hint-transforms-a-sort-merge-join-into-a-nested-loops-join/#comment-3991</link>
		<dc:creator><![CDATA[Charles Hooper]]></dc:creator>
		<pubDate>Fri, 30 Sep 2011 18:34:36 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=5492#comment-3991</guid>
		<description><![CDATA[Here is another fun experiment.  Page 502 of the book (that was mentioned at the beginning of this article) showed how to use the OPTIMIZER_FEATURES_ENABLE hint:
&lt;blockquote&gt;
&lt;pre&gt;
SELECT /*+ optimizer_features_enable(&#039;10.2&#039;) */ *
FROM EMP JOIN DEPT USING(DEPTNO);
&lt;/pre&gt;
&lt;/blockquote&gt;

That hint does not look right.  Why?
&lt;pre&gt;
SQL&gt; ALTER SESSION SET OPTIMIZER_FEATURES_ENABLE=&#039;10.2&#039;;
ERROR:
ORA-00096: invalid value 10.2 for parameter optimizer_features_enable, must be
from among 11.2.0.2.1, 11.2.0.2, 11.2.0.1, 11.1.0.7, 11.1.0.6, 10.2.0.5,
10.2.0.4, 10.2.0.3, 10.2.0.2, 10.2.0.1, 10.1.0.5, 10.1.0.4, 10.1.0.3, 10.1.0,
9.2.0.8, 9.2.0, 9.0.1, 9.0.0, 8.1.7, 8.1.6, 8.1.5, 8.1.4, 8.1.3, 8.1.0, 8.0.7,
8.0.6, 8.0.5, 8.0.4, 8.0.3, 8.0.0
&lt;/pre&gt;

OK, so changing the parameter directly to 10.2 does not work.  What happens when it is attempted in a hint?  Here is a test script to see what happens:
&lt;pre&gt;
ALTER SESSION SET TRACEFILE_IDENTIFIER = &#039;USE_HASH2_10053&#039;;
ALTER SESSION SET EVENTS &#039;10053 TRACE NAME CONTEXT FOREVER, LEVEL 1&#039;;

SET AUTOTRACE TRACEONLY EXPLAIN
SELECT /*+ OPTIMIZER_FEATURES_ENABLE(&#039;10.2&#039;) USE_HASH(T1 T2) */
  *
FROM
  T1,
  T2
WHERE
  T1.RN&gt;T2.RN;
 
ALTER SESSION SET EVENTS &#039;10053 TRACE NAME CONTEXT OFF&#039;;
 
ALTER SESSION SET TRACEFILE_IDENTIFIER = &#039;USE_HASH3_10053&#039;;
ALTER SESSION SET EVENTS &#039;10053 TRACE NAME CONTEXT FOREVER, LEVEL 1&#039;;
 
SELECT /*+ USE_HASH(T1 T2) OPTIMIZER_FEATURES_ENABLE(&#039;10.2&#039;) */
  *
FROM
  T1,
  T2
WHERE
  T1.RN&gt;T2.RN;
 
ALTER SESSION SET EVENTS &#039;10053 TRACE NAME CONTEXT OFF&#039;;
 
ALTER SESSION SET TRACEFILE_IDENTIFIER = &#039;USE_HASH4_10053&#039;;
ALTER SESSION SET EVENTS &#039;10053 TRACE NAME CONTEXT FOREVER, LEVEL 1&#039;;
 
SELECT /*+ OPTIMIZER_FEATURES_ENABLE(&#039;10.2.0.4&#039;) USE_HASH(T1 T2) */
  *
FROM
  T1,
  T2
WHERE
  T1.RN&gt;T2.RN;
 
ALTER SESSION SET EVENTS &#039;10053 TRACE NAME CONTEXT OFF&#039;;
&lt;/pre&gt;

The results follow:
&lt;pre&gt;
SQL&gt; SELECT /*+ OPTIMIZER_FEATURES_ENABLE(&#039;10.2&#039;) USE_HASH(T1 T2) */
  2    *
  3  FROM
  4    T1,
  5    T2
  6  WHERE
  7    T1.RN&gt;T2.RN;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 412793182

----------------------------------------------------------------------------
&#124; Id  &#124; Operation           &#124; Name &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
----------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT    &#124;      &#124;  4950 &#124; 29700 &#124;     9  (34)&#124; 00:00:01 &#124;
&#124;   1 &#124;  MERGE JOIN         &#124;      &#124;  4950 &#124; 29700 &#124;     9  (34)&#124; 00:00:01 &#124;
&#124;   2 &#124;   SORT JOIN         &#124;      &#124;   100 &#124;   300 &#124;     4  (25)&#124; 00:00:01 &#124;
&#124;   3 &#124;    TABLE ACCESS FULL&#124; T1   &#124;   100 &#124;   300 &#124;     3   (0)&#124; 00:00:01 &#124;
&#124;*  4 &#124;   SORT JOIN         &#124;      &#124;   100 &#124;   300 &#124;     4  (25)&#124; 00:00:01 &#124;
&#124;   5 &#124;    TABLE ACCESS FULL&#124; T2   &#124;   100 &#124;   300 &#124;     3   (0)&#124; 00:00:01 &#124;
----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   4 - access(INTERNAL_FUNCTION(&quot;T1&quot;.&quot;RN&quot;)&gt;INTERNAL_FUNCTION(&quot;T2&quot;.&quot;RN&quot;))
       filter(INTERNAL_FUNCTION(&quot;T1&quot;.&quot;RN&quot;)&gt;INTERNAL_FUNCTION(&quot;T2&quot;.&quot;RN&quot;))
&lt;/pre&gt;
Note that in the above, the error in the OPTIMIZER_FEATURES_ENABLE hint caused the optimizer to apparently not see the USE_HASH hint.

So, what happens when we reverse the order of the hints?:
&lt;pre&gt;
SQL&gt; SELECT /*+ USE_HASH(T1 T2) OPTIMIZER_FEATURES_ENABLE(&#039;10.2&#039;) */
  2    *
  3  FROM
  4    T1,
  5    T2
  6  WHERE
  7    T1.RN&gt;T2.RN;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 1967407726
 
---------------------------------------------------------------------------
&#124; Id  &#124; Operation          &#124; Name &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
---------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT   &#124;      &#124;  4950 &#124; 29700 &#124;   144   (5)&#124; 00:00:01 &#124;
&#124;   1 &#124;  NESTED LOOPS      &#124;      &#124;  4950 &#124; 29700 &#124;   144   (5)&#124; 00:00:01 &#124;
&#124;   2 &#124;   TABLE ACCESS FULL&#124; T1   &#124;   100 &#124;   300 &#124;     3   (0)&#124; 00:00:01 &#124;
&#124;*  3 &#124;   TABLE ACCESS FULL&#124; T2   &#124;    50 &#124;   150 &#124;     1   (0)&#124; 00:00:01 &#124;
---------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - filter(&quot;T1&quot;.&quot;RN&quot;&gt;&quot;T2&quot;.&quot;RN&quot;)
&lt;/pre&gt;
Note in the above that the optimizer saw the USE_HASH hint (even though a nested loops join was the result).

Now for the final part of the output, a properly specified OPTIMIZER_FEATURES_ENABLE:
&lt;pre&gt;
SQL&gt; SELECT /*+ OPTIMIZER_FEATURES_ENABLE(&#039;10.2.0.4&#039;) USE_HASH(T1 T2) */
  2    *
  3  FROM
  4    T1,
  5    T2
  6  WHERE
  7    T1.RN&gt;T2.RN;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 1967407726
 
---------------------------------------------------------------------------
&#124; Id  &#124; Operation          &#124; Name &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
---------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT   &#124;      &#124;   500 &#124;  3000 &#124;   144   (5)&#124; 00:00:01 &#124;
&#124;   1 &#124;  NESTED LOOPS      &#124;      &#124;   500 &#124;  3000 &#124;   144   (5)&#124; 00:00:01 &#124;
&#124;   2 &#124;   TABLE ACCESS FULL&#124; T1   &#124;   100 &#124;   300 &#124;     3   (0)&#124; 00:00:01 &#124;
&#124;*  3 &#124;   TABLE ACCESS FULL&#124; T2   &#124;     5 &#124;    15 &#124;     1   (0)&#124; 00:00:01 &#124;
---------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - filter(&quot;T1&quot;.&quot;RN&quot;&gt;&quot;T2&quot;.&quot;RN&quot;)
&lt;/pre&gt;
Note that in the above, the optimizer saw the USE_HASH hint (even though a nested loops join was the result).]]></description>
		<content:encoded><![CDATA[<p>Here is another fun experiment.  Page 502 of the book (that was mentioned at the beginning of this article) showed how to use the OPTIMIZER_FEATURES_ENABLE hint:</p>
<blockquote>
<pre>
SELECT /*+ optimizer_features_enable('10.2') */ *
FROM EMP JOIN DEPT USING(DEPTNO);
</pre>
</blockquote>
<p>That hint does not look right.  Why?</p>
<pre>
SQL&gt; ALTER SESSION SET OPTIMIZER_FEATURES_ENABLE='10.2';
ERROR:
ORA-00096: invalid value 10.2 for parameter optimizer_features_enable, must be
from among 11.2.0.2.1, 11.2.0.2, 11.2.0.1, 11.1.0.7, 11.1.0.6, 10.2.0.5,
10.2.0.4, 10.2.0.3, 10.2.0.2, 10.2.0.1, 10.1.0.5, 10.1.0.4, 10.1.0.3, 10.1.0,
9.2.0.8, 9.2.0, 9.0.1, 9.0.0, 8.1.7, 8.1.6, 8.1.5, 8.1.4, 8.1.3, 8.1.0, 8.0.7,
8.0.6, 8.0.5, 8.0.4, 8.0.3, 8.0.0
</pre>
<p>OK, so changing the parameter directly to 10.2 does not work.  What happens when it is attempted in a hint?  Here is a test script to see what happens:</p>
<pre>
ALTER SESSION SET TRACEFILE_IDENTIFIER = 'USE_HASH2_10053';
ALTER SESSION SET EVENTS '10053 TRACE NAME CONTEXT FOREVER, LEVEL 1';

SET AUTOTRACE TRACEONLY EXPLAIN
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('10.2') USE_HASH(T1 T2) */
  *
FROM
  T1,
  T2
WHERE
  T1.RN&gt;T2.RN;
 
ALTER SESSION SET EVENTS '10053 TRACE NAME CONTEXT OFF';
 
ALTER SESSION SET TRACEFILE_IDENTIFIER = 'USE_HASH3_10053';
ALTER SESSION SET EVENTS '10053 TRACE NAME CONTEXT FOREVER, LEVEL 1';
 
SELECT /*+ USE_HASH(T1 T2) OPTIMIZER_FEATURES_ENABLE('10.2') */
  *
FROM
  T1,
  T2
WHERE
  T1.RN&gt;T2.RN;
 
ALTER SESSION SET EVENTS '10053 TRACE NAME CONTEXT OFF';
 
ALTER SESSION SET TRACEFILE_IDENTIFIER = 'USE_HASH4_10053';
ALTER SESSION SET EVENTS '10053 TRACE NAME CONTEXT FOREVER, LEVEL 1';
 
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('10.2.0.4') USE_HASH(T1 T2) */
  *
FROM
  T1,
  T2
WHERE
  T1.RN&gt;T2.RN;
 
ALTER SESSION SET EVENTS '10053 TRACE NAME CONTEXT OFF';
</pre>
<p>The results follow:</p>
<pre>
SQL&gt; SELECT /*+ OPTIMIZER_FEATURES_ENABLE('10.2') USE_HASH(T1 T2) */
  2    *
  3  FROM
  4    T1,
  5    T2
  6  WHERE
  7    T1.RN&gt;T2.RN;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 412793182

----------------------------------------------------------------------------
| Id  | Operation           | Name | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |  4950 | 29700 |     9  (34)| 00:00:01 |
|   1 |  MERGE JOIN         |      |  4950 | 29700 |     9  (34)| 00:00:01 |
|   2 |   SORT JOIN         |      |   100 |   300 |     4  (25)| 00:00:01 |
|   3 |    TABLE ACCESS FULL| T1   |   100 |   300 |     3   (0)| 00:00:01 |
|*  4 |   SORT JOIN         |      |   100 |   300 |     4  (25)| 00:00:01 |
|   5 |    TABLE ACCESS FULL| T2   |   100 |   300 |     3   (0)| 00:00:01 |
----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   4 - access(INTERNAL_FUNCTION("T1"."RN")&gt;INTERNAL_FUNCTION("T2"."RN"))
       filter(INTERNAL_FUNCTION("T1"."RN")&gt;INTERNAL_FUNCTION("T2"."RN"))
</pre>
<p>Note that in the above, the error in the OPTIMIZER_FEATURES_ENABLE hint caused the optimizer to apparently not see the USE_HASH hint.</p>
<p>So, what happens when we reverse the order of the hints?:</p>
<pre>
SQL&gt; SELECT /*+ USE_HASH(T1 T2) OPTIMIZER_FEATURES_ENABLE('10.2') */
  2    *
  3  FROM
  4    T1,
  5    T2
  6  WHERE
  7    T1.RN&gt;T2.RN;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 1967407726
 
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |  4950 | 29700 |   144   (5)| 00:00:01 |
|   1 |  NESTED LOOPS      |      |  4950 | 29700 |   144   (5)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| T1   |   100 |   300 |     3   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| T2   |    50 |   150 |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - filter("T1"."RN"&gt;"T2"."RN")
</pre>
<p>Note in the above that the optimizer saw the USE_HASH hint (even though a nested loops join was the result).</p>
<p>Now for the final part of the output, a properly specified OPTIMIZER_FEATURES_ENABLE:</p>
<pre>
SQL&gt; SELECT /*+ OPTIMIZER_FEATURES_ENABLE('10.2.0.4') USE_HASH(T1 T2) */
  2    *
  3  FROM
  4    T1,
  5    T2
  6  WHERE
  7    T1.RN&gt;T2.RN;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 1967407726
 
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |   500 |  3000 |   144   (5)| 00:00:01 |
|   1 |  NESTED LOOPS      |      |   500 |  3000 |   144   (5)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| T1   |   100 |   300 |     3   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| T2   |     5 |    15 |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - filter("T1"."RN"&gt;"T2"."RN")
</pre>
<p>Note that in the above, the optimizer saw the USE_HASH hint (even though a nested loops join was the result).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Charles Hooper</title>
		<link>http://hoopercharles.wordpress.com/2011/09/30/invalid-hints-are-silently-ignored-an-invalid-use_hash-hint-transforms-a-sort-merge-join-into-a-nested-loops-join/#comment-3990</link>
		<dc:creator><![CDATA[Charles Hooper]]></dc:creator>
		<pubDate>Fri, 30 Sep 2011 15:56:17 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=5492#comment-3990</guid>
		<description><![CDATA[Just to be complete, reversing the order of the hints, placing the undocumented FAST hint last:
&lt;pre&gt;
SELECT /*+ USE_HASH(T1 T2) FAST(TRUE) */
  *
FROM
  T1,
  T2
WHERE
  T1.RN&gt;T2.RN;
&lt;/pre&gt;
 
&lt;pre&gt;
SQL&gt; SELECT /*+ USE_HASH(T1 T2) FAST(TRUE) */
  2    *
  3  FROM
  4    T1,
  5    T2
  6  WHERE
  7    T1.RN&gt;T2.RN;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 1967407726
 
---------------------------------------------------------------------------
&#124; Id  &#124; Operation          &#124; Name &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
---------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT   &#124;      &#124;  4950 &#124; 29700 &#124;   144   (5)&#124; 00:00:01 &#124;
&#124;   1 &#124;  NESTED LOOPS      &#124;      &#124;  4950 &#124; 29700 &#124;   144   (5)&#124; 00:00:01 &#124;
&#124;   2 &#124;   TABLE ACCESS FULL&#124; T1   &#124;   100 &#124;   300 &#124;     3   (0)&#124; 00:00:01 &#124;
&#124;*  3 &#124;   TABLE ACCESS FULL&#124; T2   &#124;    50 &#124;   150 &#124;     1   (0)&#124; 00:00:01 &#124;
---------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - filter(&quot;T1&quot;.&quot;RN&quot;&gt;&quot;T2&quot;.&quot;RN&quot;)
&lt;/pre&gt;

To the casual observer, the order of the hints potentially matters.  However, for those who read the articles at the start of this blog article, it is quite clear why the execution plan reverted back from the sort-merge join (well, almost... why was that 10053 trace enabled?).]]></description>
		<content:encoded><![CDATA[<p>Just to be complete, reversing the order of the hints, placing the undocumented FAST hint last:</p>
<pre>
SELECT /*+ USE_HASH(T1 T2) FAST(TRUE) */
  *
FROM
  T1,
  T2
WHERE
  T1.RN&gt;T2.RN;
</pre>
<pre>
SQL&gt; SELECT /*+ USE_HASH(T1 T2) FAST(TRUE) */
  2    *
  3  FROM
  4    T1,
  5    T2
  6  WHERE
  7    T1.RN&gt;T2.RN;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 1967407726
 
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |  4950 | 29700 |   144   (5)| 00:00:01 |
|   1 |  NESTED LOOPS      |      |  4950 | 29700 |   144   (5)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| T1   |   100 |   300 |     3   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| T2   |    50 |   150 |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - filter("T1"."RN"&gt;"T2"."RN")
</pre>
<p>To the casual observer, the order of the hints potentially matters.  However, for those who read the articles at the start of this blog article, it is quite clear why the execution plan reverted back from the sort-merge join (well, almost&#8230; why was that 10053 trace enabled?).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Charles Hooper</title>
		<link>http://hoopercharles.wordpress.com/2011/09/30/invalid-hints-are-silently-ignored-an-invalid-use_hash-hint-transforms-a-sort-merge-join-into-a-nested-loops-join/#comment-3989</link>
		<dc:creator><![CDATA[Charles Hooper]]></dc:creator>
		<pubDate>Fri, 30 Sep 2011 15:46:32 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=5492#comment-3989</guid>
		<description><![CDATA[Nigel, that is an interesting perspective.

Here is a little more fun (explained in the links at the top of this article).  The undocumented FAST hint :-) :
&lt;pre&gt;
SELECT /*+ FAST=TRUE USE_HASH(T1 T2) */
  *
FROM
  T1,
  T2
WHERE
  T1.RN&gt;T2.RN;
&lt;/pre&gt;
&lt;pre&gt;
SQL&gt; SELECT /*+ FAST=TRUE USE_HASH(T1 T2) */
  2    *
  3  FROM
  4    T1,
  5    T2
  6  WHERE
  7    T1.RN&gt;T2.RN;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 412793182
 
----------------------------------------------------------------------------
&#124; Id  &#124; Operation           &#124; Name &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
----------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT    &#124;      &#124;  4950 &#124; 29700 &#124;     9  (34)&#124; 00:00:01 &#124;
&#124;   1 &#124;  MERGE JOIN         &#124;      &#124;  4950 &#124; 29700 &#124;     9  (34)&#124; 00:00:01 &#124;
&#124;   2 &#124;   SORT JOIN         &#124;      &#124;   100 &#124;   300 &#124;     4  (25)&#124; 00:00:01 &#124;
&#124;   3 &#124;    TABLE ACCESS FULL&#124; T1   &#124;   100 &#124;   300 &#124;     3   (0)&#124; 00:00:01 &#124;
&#124;*  4 &#124;   SORT JOIN         &#124;      &#124;   100 &#124;   300 &#124;     4  (25)&#124; 00:00:01 &#124;
&#124;   5 &#124;    TABLE ACCESS FULL&#124; T2   &#124;   100 &#124;   300 &#124;     3   (0)&#124; 00:00:01 &#124;
----------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   4 - access(INTERNAL_FUNCTION(&quot;T1&quot;.&quot;RN&quot;)&gt;INTERNAL_FUNCTION(&quot;T2&quot;.&quot;RN&quot;))
       filter(INTERNAL_FUNCTION(&quot;T1&quot;.&quot;RN&quot;)&gt;INTERNAL_FUNCTION(&quot;T2&quot;.&quot;RN&quot;))
&lt;/pre&gt;
 
Trying again, just to make certain that the syntax of the undocumented hint is correct:
&lt;pre&gt;
SELECT /*+ FAST(TRUE) USE_HASH(T1 T2) */
  *
FROM
  T1,
  T2
WHERE
  T1.RN&gt;T2.RN;
&lt;/pre&gt;
&lt;pre&gt; 
SQL&gt; SELECT /*+ FAST(TRUE) USE_HASH(T1 T2) */
  2    *
  3  FROM
  4    T1,
  5    T2
  6  WHERE
  7    T1.RN&gt;T2.RN;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 412793182
 
----------------------------------------------------------------------------
&#124; Id  &#124; Operation           &#124; Name &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
----------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT    &#124;      &#124;  4950 &#124; 29700 &#124;     9  (34)&#124; 00:00:01 &#124;
&#124;   1 &#124;  MERGE JOIN         &#124;      &#124;  4950 &#124; 29700 &#124;     9  (34)&#124; 00:00:01 &#124;
&#124;   2 &#124;   SORT JOIN         &#124;      &#124;   100 &#124;   300 &#124;     4  (25)&#124; 00:00:01 &#124;
&#124;   3 &#124;    TABLE ACCESS FULL&#124; T1   &#124;   100 &#124;   300 &#124;     3   (0)&#124; 00:00:01 &#124;
&#124;*  4 &#124;   SORT JOIN         &#124;      &#124;   100 &#124;   300 &#124;     4  (25)&#124; 00:00:01 &#124;
&#124;   5 &#124;    TABLE ACCESS FULL&#124; T2   &#124;   100 &#124;   300 &#124;     3   (0)&#124; 00:00:01 &#124;
----------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   4 - access(INTERNAL_FUNCTION(&quot;T1&quot;.&quot;RN&quot;)&gt;INTERNAL_FUNCTION(&quot;T2&quot;.&quot;RN&quot;))
       filter(INTERNAL_FUNCTION(&quot;T1&quot;.&quot;RN&quot;)&gt;INTERNAL_FUNCTION(&quot;T2&quot;.&quot;RN&quot;))
&lt;/pre&gt;]]></description>
		<content:encoded><![CDATA[<p>Nigel, that is an interesting perspective.</p>
<p>Here is a little more fun (explained in the links at the top of this article).  The undocumented FAST hint <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  :</p>
<pre>
SELECT /*+ FAST=TRUE USE_HASH(T1 T2) */
  *
FROM
  T1,
  T2
WHERE
  T1.RN&gt;T2.RN;
</pre>
<pre>
SQL&gt; SELECT /*+ FAST=TRUE USE_HASH(T1 T2) */
  2    *
  3  FROM
  4    T1,
  5    T2
  6  WHERE
  7    T1.RN&gt;T2.RN;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 412793182
 
----------------------------------------------------------------------------
| Id  | Operation           | Name | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |  4950 | 29700 |     9  (34)| 00:00:01 |
|   1 |  MERGE JOIN         |      |  4950 | 29700 |     9  (34)| 00:00:01 |
|   2 |   SORT JOIN         |      |   100 |   300 |     4  (25)| 00:00:01 |
|   3 |    TABLE ACCESS FULL| T1   |   100 |   300 |     3   (0)| 00:00:01 |
|*  4 |   SORT JOIN         |      |   100 |   300 |     4  (25)| 00:00:01 |
|   5 |    TABLE ACCESS FULL| T2   |   100 |   300 |     3   (0)| 00:00:01 |
----------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   4 - access(INTERNAL_FUNCTION("T1"."RN")&gt;INTERNAL_FUNCTION("T2"."RN"))
       filter(INTERNAL_FUNCTION("T1"."RN")&gt;INTERNAL_FUNCTION("T2"."RN"))
</pre>
<p>Trying again, just to make certain that the syntax of the undocumented hint is correct:</p>
<pre>
SELECT /*+ FAST(TRUE) USE_HASH(T1 T2) */
  *
FROM
  T1,
  T2
WHERE
  T1.RN&gt;T2.RN;
</pre>
<pre> 
SQL&gt; SELECT /*+ FAST(TRUE) USE_HASH(T1 T2) */
  2    *
  3  FROM
  4    T1,
  5    T2
  6  WHERE
  7    T1.RN&gt;T2.RN;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 412793182
 
----------------------------------------------------------------------------
| Id  | Operation           | Name | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |  4950 | 29700 |     9  (34)| 00:00:01 |
|   1 |  MERGE JOIN         |      |  4950 | 29700 |     9  (34)| 00:00:01 |
|   2 |   SORT JOIN         |      |   100 |   300 |     4  (25)| 00:00:01 |
|   3 |    TABLE ACCESS FULL| T1   |   100 |   300 |     3   (0)| 00:00:01 |
|*  4 |   SORT JOIN         |      |   100 |   300 |     4  (25)| 00:00:01 |
|   5 |    TABLE ACCESS FULL| T2   |   100 |   300 |     3   (0)| 00:00:01 |
----------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   4 - access(INTERNAL_FUNCTION("T1"."RN")&gt;INTERNAL_FUNCTION("T2"."RN"))
       filter(INTERNAL_FUNCTION("T1"."RN")&gt;INTERNAL_FUNCTION("T2"."RN"))
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Nigel Thomas</title>
		<link>http://hoopercharles.wordpress.com/2011/09/30/invalid-hints-are-silently-ignored-an-invalid-use_hash-hint-transforms-a-sort-merge-join-into-a-nested-loops-join/#comment-3988</link>
		<dc:creator><![CDATA[Nigel Thomas]]></dc:creator>
		<pubDate>Fri, 30 Sep 2011 15:30:00 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=5492#comment-3988</guid>
		<description><![CDATA[Arguably, the USE_HASH hint is not invalid - just inapplicable. An invalid hint would be something like /*+ GO_FASTER */. But your test suggests it may be misnamed - perhaps it should have been NO_USE_SORT_MERGE? That&#039;s the trouble with the CBO - what looks like a binary choice in 1990 becomes much more complex by 2011.]]></description>
		<content:encoded><![CDATA[<p>Arguably, the USE_HASH hint is not invalid &#8211; just inapplicable. An invalid hint would be something like /*+ GO_FASTER */. But your test suggests it may be misnamed &#8211; perhaps it should have been NO_USE_SORT_MERGE? That&#8217;s the trouble with the CBO &#8211; what looks like a binary choice in 1990 becomes much more complex by 2011.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
