<?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: Quiz Night</title>
	<atom:link href="http://jonathanlewis.wordpress.com/2012/01/13/quiz-night-15/feed/" rel="self" type="application/rss+xml" />
	<link>http://jonathanlewis.wordpress.com/2012/01/13/quiz-night-15/</link>
	<description>Just another Oracle weblog</description>
	<lastBuildDate>Wed, 19 Jun 2013 18:51:29 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
	<item>
		<title>By: Jonathan Lewis</title>
		<link>http://jonathanlewis.wordpress.com/2012/01/13/quiz-night-15/#comment-44687</link>
		<dc:creator><![CDATA[Jonathan Lewis]]></dc:creator>
		<pubDate>Thu, 26 Jan 2012 21:48:57 +0000</pubDate>
		<guid isPermaLink="false">http://jonathanlewis.wordpress.com/?p=8101#comment-44687</guid>
		<description><![CDATA[Valentin,
Although Oracle reports an index name in the final execution plan output, if you check the outline section of the plan - dbms_xplan.display(null,null,&#039;outline&#039;) you will find that it is still thinking of the index in terms of an ordered list of columns.]]></description>
		<content:encoded><![CDATA[<p>Valentin,<br />
Although Oracle reports an index name in the final execution plan output, if you check the outline section of the plan &#8211; dbms_xplan.display(null,null,&#8217;outline&#8217;) you will find that it is still thinking of the index in terms of an ordered list of columns.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jonathan Lewis</title>
		<link>http://jonathanlewis.wordpress.com/2012/01/13/quiz-night-15/#comment-44686</link>
		<dc:creator><![CDATA[Jonathan Lewis]]></dc:creator>
		<pubDate>Thu, 26 Jan 2012 21:47:10 +0000</pubDate>
		<guid isPermaLink="false">http://jonathanlewis.wordpress.com/?p=8101#comment-44686</guid>
		<description><![CDATA[Charles,

Thanks for that. I&#039;ve always found it harder to find things in the manuals since they went electronic, but I&#039;m surprised I hadn&#039;t noticed that before. (Maybe it wasn&#039;t there when I first checked, or maybe I only checked in the 10.1 manual).

To return the favour - the /*+ index(v.e2.e3 emp_job_ix) */ format goes all the way back to Oracle 8, and is the form used to supply hints against tables inside view definitions. If it actually works it means that e2 is a view inside v, and e3 is a view inside e2.]]></description>
		<content:encoded><![CDATA[<p>Charles,</p>
<p>Thanks for that. I&#8217;ve always found it harder to find things in the manuals since they went electronic, but I&#8217;m surprised I hadn&#8217;t noticed that before. (Maybe it wasn&#8217;t there when I first checked, or maybe I only checked in the 10.1 manual).</p>
<p>To return the favour &#8211; the /*+ index(v.e2.e3 emp_job_ix) */ format goes all the way back to Oracle 8, and is the form used to supply hints against tables inside view definitions. If it actually works it means that e2 is a view inside v, and e3 is a view inside e2.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jonathan Lewis</title>
		<link>http://jonathanlewis.wordpress.com/2012/01/13/quiz-night-15/#comment-44685</link>
		<dc:creator><![CDATA[Jonathan Lewis]]></dc:creator>
		<pubDate>Thu, 26 Jan 2012 21:42:40 +0000</pubDate>
		<guid isPermaLink="false">http://jonathanlewis.wordpress.com/?p=8101#comment-44685</guid>
		<description><![CDATA[Valentin,

That&#039;s an interesting observation. 
The behaviour probably varies with version of Oracle, so it&#039;s worth having a couple of simple test cases so that you can check what&#039;s going on in each upgrade and patch.]]></description>
		<content:encoded><![CDATA[<p>Valentin,</p>
<p>That&#8217;s an interesting observation.<br />
The behaviour probably varies with version of Oracle, so it&#8217;s worth having a couple of simple test cases so that you can check what&#8217;s going on in each upgrade and patch.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Non-Specific Index Hints &#171; Charles Hooper&#039;s Oracle Notes</title>
		<link>http://jonathanlewis.wordpress.com/2012/01/13/quiz-night-15/#comment-44650</link>
		<dc:creator><![CDATA[Non-Specific Index Hints &#171; Charles Hooper&#039;s Oracle Notes]]></dc:creator>
		<pubDate>Tue, 24 Jan 2012 20:39:41 +0000</pubDate>
		<guid isPermaLink="false">http://jonathanlewis.wordpress.com/?p=8101#comment-44650</guid>
		<description><![CDATA[[...] reminded that it was possible to create non-specific index hints that specify table columns when a recent quiz was posted that asked to find specific cases where the behavior is other than expected with the [...]]]></description>
		<content:encoded><![CDATA[<p>[...] reminded that it was possible to create non-specific index hints that specify table columns when a recent quiz was posted that asked to find specific cases where the behavior is other than expected with the [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Quiz Night &#171; Oracle Scratchpad</title>
		<link>http://jonathanlewis.wordpress.com/2012/01/13/quiz-night-15/#comment-44532</link>
		<dc:creator><![CDATA[Quiz Night &#171; Oracle Scratchpad]]></dc:creator>
		<pubDate>Thu, 19 Jan 2012 08:51:57 +0000</pubDate>
		<guid isPermaLink="false">http://jonathanlewis.wordpress.com/?p=8101#comment-44532</guid>
		<description><![CDATA[[...] my previous post, I made the comment:  In general, if you have a three-column index that starts with the same [...]]]></description>
		<content:encoded><![CDATA[<p>[...] my previous post, I made the comment:  In general, if you have a three-column index that starts with the same [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Valentin Nikotin</title>
		<link>http://jonathanlewis.wordpress.com/2012/01/13/quiz-night-15/#comment-44448</link>
		<dc:creator><![CDATA[Valentin Nikotin]]></dc:creator>
		<pubDate>Sun, 15 Jan 2012 20:57:08 +0000</pubDate>
		<guid isPermaLink="false">http://jonathanlewis.wordpress.com/?p=8101#comment-44448</guid>
		<description><![CDATA[The another example of the situation when Oracle doesn&#039;t perform correctly new-style hint, while old-style works fine, is a hint for table through a db link. The hint in the query on the remote side will have ??? instead of the index name:

[sourcecode language=&quot;SQL&quot; collapse=&quot;true&quot;]
SQL&gt; alter system flush shared_pool;

System altered.

SQL&gt; select /*+ index(t (a b))*/ * from u1.abc@selflink t where rownum = 1;

         A          B          C
---------- ---------- ----------
       362        362        362

SQL&gt; select sql_text, executions from v$sql where sql_text like &#039;SELECT%ABC%&#039;;

SQL_TEXT                                                                                        EXECUTIONS
----------------------------------------------------------------------------------------------- ----------
SELECT /*+ FULL(P) +*/ * FROM &quot;U1&quot;.&quot;ABC&quot; P                                                               0
SELECT /*+ INDEX (&quot;A1&quot; ???) */ &quot;A1&quot;.&quot;A&quot;,&quot;A1&quot;.&quot;B&quot;,&quot;A1&quot;.&quot;C&quot; FROM &quot;U1&quot;.&quot;ABC&quot; &quot;A1&quot; WHERE ROWNUM=1            1

SQL&gt; alter system flush shared_pool;

System altered.

SQL&gt; select /*+ index(t ind)*/ * from u1.abc@selflink t where rownum = 1;

         A          B          C
---------- ---------- ----------
         1          1          1

SQL&gt; select sql_text, executions from v$sql where sql_text like &#039;SELECT%ABC%&#039;;

SQL_TEXT                                                                                        EXECUTIONS
----------------------------------------------------------------------------------------------- ----------
SELECT /*+ FULL(P) +*/ * FROM &quot;U1&quot;.&quot;ABC&quot; P                                                               0
SELECT /*+ INDEX (&quot;A1&quot; &quot;IND&quot;) */ &quot;A1&quot;.&quot;A&quot;,&quot;A1&quot;.&quot;B&quot;,&quot;A1&quot;.&quot;C&quot; FROM &quot;U1&quot;.&quot;ABC&quot; &quot;A1&quot; WHERE ROWNUM=1          1
[/sourcecode]]]></description>
		<content:encoded><![CDATA[<p>The another example of the situation when Oracle doesn&#8217;t perform correctly new-style hint, while old-style works fine, is a hint for table through a db link. The hint in the query on the remote side will have ??? instead of the index name:</p>
<pre class="brush: sql; collapse: true; light: false; title: ; toolbar: true; notranslate">
SQL&gt; alter system flush shared_pool;

System altered.

SQL&gt; select /*+ index(t (a b))*/ * from u1.abc@selflink t where rownum = 1;

         A          B          C
---------- ---------- ----------
       362        362        362

SQL&gt; select sql_text, executions from v$sql where sql_text like 'SELECT%ABC%';

SQL_TEXT                                                                                        EXECUTIONS
----------------------------------------------------------------------------------------------- ----------
SELECT /*+ FULL(P) +*/ * FROM &quot;U1&quot;.&quot;ABC&quot; P                                                               0
SELECT /*+ INDEX (&quot;A1&quot; ???) */ &quot;A1&quot;.&quot;A&quot;,&quot;A1&quot;.&quot;B&quot;,&quot;A1&quot;.&quot;C&quot; FROM &quot;U1&quot;.&quot;ABC&quot; &quot;A1&quot; WHERE ROWNUM=1            1

SQL&gt; alter system flush shared_pool;

System altered.

SQL&gt; select /*+ index(t ind)*/ * from u1.abc@selflink t where rownum = 1;

         A          B          C
---------- ---------- ----------
         1          1          1

SQL&gt; select sql_text, executions from v$sql where sql_text like 'SELECT%ABC%';

SQL_TEXT                                                                                        EXECUTIONS
----------------------------------------------------------------------------------------------- ----------
SELECT /*+ FULL(P) +*/ * FROM &quot;U1&quot;.&quot;ABC&quot; P                                                               0
SELECT /*+ INDEX (&quot;A1&quot; &quot;IND&quot;) */ &quot;A1&quot;.&quot;A&quot;,&quot;A1&quot;.&quot;B&quot;,&quot;A1&quot;.&quot;C&quot; FROM &quot;U1&quot;.&quot;ABC&quot; &quot;A1&quot; WHERE ROWNUM=1          1
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Charles Hooper</title>
		<link>http://jonathanlewis.wordpress.com/2012/01/13/quiz-night-15/#comment-44446</link>
		<dc:creator><![CDATA[Charles Hooper]]></dc:creator>
		<pubDate>Sun, 15 Jan 2012 20:04:46 +0000</pubDate>
		<guid isPermaLink="false">http://jonathanlewis.wordpress.com/?p=8101#comment-44446</guid>
		<description><![CDATA[Jonathan,

It might be the case that the original basis for your observation is found in the Oracle Database documentation (found in the 10.2 and 11.2 documentation library - a bit more information is provided in the 11.2 documentation libary (in section 19.2.4 Specifying Complex Index Hints), but the link to create the V view (link to Example 16-3) was removed).
http://docs.oracle.com/cd/B19306_01/server.102/b14211/hintsref.htm#PFGRF50105

&lt;blockquote&gt;
* table specifies the name

* column specifies the name of a column in the specified table

** The columns can optionally be prefixed with table qualifiers allowing the hint to specify bitmap join indexes where the index columns are on a different table than the indexed table. If tables qualifiers are present, they must be base tables, not aliases in the query.

** Each column in an index specification must be a base column in the specified table, not an expression. Function-based indexes cannot be hinted using a column specification unless the columns specified in the index specification form the prefix of a function-based index.

The hint is resolved as follows:
* If an index name is specified, only that index is considered.

* If a column list is specified and an index exists whose columns match the specified columns in number and order, only that index is considered. If no such index exists, then any index on the table with the specified columns as the prefix in the order specified is considered. In either case, the behavior is exactly as if the user had specified the same hint individually on all the matching indexes.

For example, in Example 16-3 the job_history table has a single-column index on the employee_id column and a concatenated index on employee_id and start_date columns. To specifically instruct the optimizer on index use, the query can be hinted as follows:
[code]
SELECT /*+ INDEX(v.j jhist_employee_ix (employee_id start_date)) */ * FROM v;
[/code]
&lt;/blockquote&gt;

The above quote agrees with your statement.  However, the index hint example provided in the above quote does not appear to be valid because both an index name and a column list are specified.  In light of the apparently invalid index hint found in the 10.2 and 11.2 documentation, a bit more experimentation might be required.

I find that it is interesting that the following index hint found in the documentation works:
[code]
SELECT /*+ INDEX(v.e2.e3 emp_job_ix) */  * 
  FROM v;
[/code]]]></description>
		<content:encoded><![CDATA[<p>Jonathan,</p>
<p>It might be the case that the original basis for your observation is found in the Oracle Database documentation (found in the 10.2 and 11.2 documentation library &#8211; a bit more information is provided in the 11.2 documentation libary (in section 19.2.4 Specifying Complex Index Hints), but the link to create the V view (link to Example 16-3) was removed).<br />
<a href="http://docs.oracle.com/cd/B19306_01/server.102/b14211/hintsref.htm#PFGRF50105" rel="nofollow">http://docs.oracle.com/cd/B19306_01/server.102/b14211/hintsref.htm#PFGRF50105</a></p>
<blockquote><p>
* table specifies the name</p>
<p>* column specifies the name of a column in the specified table</p>
<p>** The columns can optionally be prefixed with table qualifiers allowing the hint to specify bitmap join indexes where the index columns are on a different table than the indexed table. If tables qualifiers are present, they must be base tables, not aliases in the query.</p>
<p>** Each column in an index specification must be a base column in the specified table, not an expression. Function-based indexes cannot be hinted using a column specification unless the columns specified in the index specification form the prefix of a function-based index.</p>
<p>The hint is resolved as follows:<br />
* If an index name is specified, only that index is considered.</p>
<p>* If a column list is specified and an index exists whose columns match the specified columns in number and order, only that index is considered. If no such index exists, then any index on the table with the specified columns as the prefix in the order specified is considered. In either case, the behavior is exactly as if the user had specified the same hint individually on all the matching indexes.</p>
<p>For example, in Example 16-3 the job_history table has a single-column index on the employee_id column and a concatenated index on employee_id and start_date columns. To specifically instruct the optimizer on index use, the query can be hinted as follows:</p>
<pre class="brush: plain; title: ; notranslate">
SELECT /*+ INDEX(v.j jhist_employee_ix (employee_id start_date)) */ * FROM v;
</pre>
</blockquote>
<p>The above quote agrees with your statement.  However, the index hint example provided in the above quote does not appear to be valid because both an index name and a column list are specified.  In light of the apparently invalid index hint found in the 10.2 and 11.2 documentation, a bit more experimentation might be required.</p>
<p>I find that it is interesting that the following index hint found in the documentation works:</p>
<pre class="brush: plain; title: ; notranslate">
SELECT /*+ INDEX(v.e2.e3 emp_job_ix) */  * 
  FROM v;
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Charles Hooper</title>
		<link>http://jonathanlewis.wordpress.com/2012/01/13/quiz-night-15/#comment-44440</link>
		<dc:creator><![CDATA[Charles Hooper]]></dc:creator>
		<pubDate>Sun, 15 Jan 2012 15:53:47 +0000</pubDate>
		<guid isPermaLink="false">http://jonathanlewis.wordpress.com/?p=8101#comment-44440</guid>
		<description><![CDATA[For what it is worth, I was not successful in disproving what you stated when testing Oracle Database 11.2.0.2 (although it is possible to make it appear as though what is stated is incorrect, simply by using an invalid index hint).  The test table and indexes that I started with were defined as follows:
[sourcecode]
CREATE TABLE T1 (
  C1 NUMBER NOT NULL,
  C2 NUMBER NOT NULL,
  C3 VARCHAR2(30) NOT NULL,
  C4 VARCHAR2(200));
 
INSERT INTO T1
SELECT
  MOD(ROWNUM-1, 90) * 4 C1,
  ROWNUM - 1 C2,
  TO_CHAR(ROWNUM - 1, &#039;RN&#039;) C3,
  LPAD(&#039;A&#039;,200,&#039;A&#039;) C4
FROM
  DUAL
CONNECT BY
  LEVEL&lt;=1000000;
 
CREATE INDEX IND_T1_C1_C2 ON T1(C1,C2);
CREATE INDEX IND_T1_C2_C1_C3 ON T1(C2,C1,C3);
CREATE INDEX IND_T1_C3_C1_C2 ON T1(C3,C1,C2);
 
EXEC DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=&gt;USER,TABNAME=&gt;&#039;T1&#039;,CASCADE=&gt;TRUE)
 
SET AUTOTRACE TRACEONLY EXPLAIN
SET LINESIZE 120
SET PAGESIZE 1000
[/sourcecode]
 
Unhinted, the following query accesses the index on columns C2, C1, and C3 to avoid accessing the table:
[sourcecode]
SELECT
  C1,
  C2,
  C3
FROM
  T1;
 
Plan hash value: 2374279026
 
----------------------------------------------------------------------------------------
&#124; Id  &#124; Operation            &#124; Name            &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
----------------------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT     &#124;                 &#124;  1000K&#124;    23M&#124;  1823  (11)&#124; 00:00:01 &#124;
&#124;   1 &#124;  INDEX FAST FULL SCAN&#124; IND_T1_C2_C1_C3 &#124;  1000K&#124;    23M&#124;  1823  (11)&#124; 00:00:01 &#124;
----------------------------------------------------------------------------------------
[/sourcecode]

Let&#039;s hint the optimizer to use the index on the columns C1 and C2:
[sourcecode] 
SELECT /*+ INDEX(T1 (C1 C2)) */
  C1,
  C2,
  C3
FROM
  T1;
 
Plan hash value: 3388050039
 
--------------------------------------------------------------------------------------------
&#124; Id  &#124; Operation                   &#124; Name         &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
--------------------------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT            &#124;              &#124;  1000K&#124;    23M&#124;  1012K  (1)&#124; 00:06:46 &#124;
&#124;   1 &#124;  TABLE ACCESS BY INDEX ROWID&#124; T1           &#124;  1000K&#124;    23M&#124;  1012K  (1)&#124; 00:06:46 &#124;
&#124;   2 &#124;   INDEX FULL SCAN           &#124; IND_T1_C1_C2 &#124;  1000K&#124;       &#124;  3026  (10)&#124; 00:00:02 &#124;
--------------------------------------------------------------------------------------------
[/sourcecode]
In the above, the optimizer obeyed the hint, even though the calculated cost from the unhinted plan increased from 1,823 to 1,012,000.

Let&#039;s reverse the order of the columns in the index hint:
[sourcecode]
SELECT /*+ INDEX(T1 (C2 C1)) */
  C1,
  C2,
  C3
FROM
  T1;
 
----------------------------------------------------------
Plan hash value: 1746297295

------------------------------------------------------------------------------------
&#124; Id  &#124; Operation        &#124; Name            &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
------------------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT &#124;                 &#124;  1000K&#124;    23M&#124;  5171   (6)&#124; 00:00:03 &#124;
&#124;   1 &#124;  INDEX FULL SCAN &#124; IND_T1_C2_C1_C3 &#124;  1000K&#124;    23M&#124;  5171   (6)&#124; 00:00:03 &#124;
------------------------------------------------------------------------------------
[/sourcecode]
In the above, note that the index on columns C2, C1, and C3 was used, but the cost is now calculated at 5,171 rather than 1,823 as it was in the unhinted plan.  The INDEX FAST FULL SCAN operation is now shown as an INDEX FULL SCAN operation.

We have an index on columns C2, C1, and C3, but we also have an index on columns C3, c1, and C2.  What happens when we specify the columns C3, C1, and C2 in the index hint in that order?
[sourcecode]
SELECT /*+ INDEX(T1 (C3 C1 C2)) */
  C1,
  C2,
  C3
FROM
  T1;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 2273443829
 
------------------------------------------------------------------------------------
&#124; Id  &#124; Operation        &#124; Name            &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
------------------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT &#124;                 &#124;  1000K&#124;    23M&#124;  5283   (6)&#124; 00:00:03 &#124;
&#124;   1 &#124;  INDEX FULL SCAN &#124; IND_T1_C3_C1_C2 &#124;  1000K&#124;    23M&#124;  5283   (6)&#124; 00:00:03 &#124;
------------------------------------------------------------------------------------
[/sourcecode]
An index full scan was selected to performed on the IND_T1_C3_C1_C2 index at a cost 5,283, rather than using the IND_T1_C2_C1_C3 index that previously resulted in a cost of 5,171 - so the optimizer will not alter the order of the columns in the index hint to reduce the calculated cost.

If we add a WHERE clause that places a restriction on column C2 to be less than 10, the optimizer could use a couple of different access paths.  Let&#039;s specify the columns C1 and C2 in the index hint to see which index is selected:
[sourcecode]
SELECT /*+ INDEX(T1 (C1 C2)) */
  C1,
  C2,
  C3
FROM
  T1
WHERE
  C2&lt;10;
 
Plan hash value: 1883798457
 
--------------------------------------------------------------------------------------------
&#124; Id  &#124; Operation                   &#124; Name         &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
--------------------------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT            &#124;              &#124;    10 &#124;   250 &#124;   104   (1)&#124; 00:00:01 &#124;
&#124;   1 &#124;  TABLE ACCESS BY INDEX ROWID&#124; T1           &#124;    10 &#124;   250 &#124;   104   (1)&#124; 00:00:01 &#124;
&#124;*  2 &#124;   INDEX SKIP SCAN           &#124; IND_T1_C1_C2 &#124;    10 &#124;       &#124;    93   (2)&#124; 00:00:01 &#124;
--------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access(&quot;C2&quot;&lt;10)
       filter(&quot;C2&quot;&lt;10)
[/sourcecode]
In the above, a skip scan was selected because the index with columns C1 and C2 was specified in the hint.

Let&#039;s try another example that possibly might be considered a case where the optimizer disobeys the hint or is free to change the order of the columns specified in the index hint (this might be incorrectly considered an edge case):
[sourcecode]
SELECT /*+ INDEX(T1 (C1 C2 C3)) */
  C1,
  C2,
  C3
FROM
  T1
WHERE
  C2&lt;10;
  
Plan hash value: 4150417361
 
------------------------------------------------------------------------------------
&#124; Id  &#124; Operation        &#124; Name            &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
------------------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT &#124;                 &#124;    10 &#124;   250 &#124;     3   (0)&#124; 00:00:01 &#124;
&#124;*  1 &#124;  INDEX RANGE SCAN&#124; IND_T1_C2_C1_C3 &#124;    10 &#124;   250 &#124;     3   (0)&#124; 00:00:01 &#124;
------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access(&quot;C2&quot;&lt;10)
[/sourcecode]
A quick peek at the above output might suggest that the optimizer could decide to locate an index with columns C1, C2, and C3 in any order - but I do not believe that this is the case.  I believe that the optimizer considered the index hint specified in the SQL statement as being invalid (a check of the 10053 trace might confirm).

Let&#039;s create another index and then repeat the above SQL statement.
[sourcecode]
CREATE INDEX IND_T1_C1_C2_C3 ON T1(C1,C2,C3);
 
SELECT /*+ INDEX(T1 (C1 C2 C3)) */
  C1,
  C2,
  C3
FROM
  T1
WHERE
  C2&lt;10;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 212907557
 
------------------------------------------------------------------------------------
&#124; Id  &#124; Operation        &#124; Name            &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
------------------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT &#124;                 &#124;    10 &#124;   250 &#124;    93   (2)&#124; 00:00:01 &#124;
&#124;*  1 &#124;  INDEX SKIP SCAN &#124; IND_T1_C1_C2_C3 &#124;    10 &#124;   250 &#124;    93   (2)&#124; 00:00:01 &#124;
------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access(&quot;C2&quot;&lt;10)
       filter(&quot;C2&quot;&lt;10)
[/sourcecode]
The index with the columns that matched the order of the columns in the index hint was selected, even though the calculated cost would have been lower if the optimizer were permitted to select any index with the columns listed in the index hint.

What about a case where there is an exact match between an index definition and an index hint, and there is also another index with one additional column which would avoid the table access:
[sourcecode]
SELECT /*+ INDEX(T1 (C1 C2)) */
  C1,
  C2,
  C3
FROM
  T1
WHERE
  C2&lt;10;
 
Plan hash value: 1883798457
 
--------------------------------------------------------------------------------------------
&#124; Id  &#124; Operation                   &#124; Name         &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
--------------------------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT            &#124;              &#124;    10 &#124;   250 &#124;   104   (1)&#124; 00:00:01 &#124;
&#124;   1 &#124;  TABLE ACCESS BY INDEX ROWID&#124; T1           &#124;    10 &#124;   250 &#124;   104   (1)&#124; 00:00:01 &#124;
&#124;*  2 &#124;   INDEX SKIP SCAN           &#124; IND_T1_C1_C2 &#124;    10 &#124;       &#124;    93   (2)&#124; 00:00:01 &#124;
--------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access(&quot;C2&quot;&lt;10)
       filter(&quot;C2&quot;&lt;10)
[/sourcecode]
The index that exactly match the index hint was selected.

What if we only specify in the index hint a leading column, when there are two indexes with that leading column, one of which allows the optimizer to avoid the table access:
[sourcecode] 
SELECT /*+ INDEX(T1 (C1)) */
  C1,
  C2,
  C3
FROM
  T1
WHERE
  C2&lt;10;
 
Plan hash value: 212907557
 
------------------------------------------------------------------------------------
&#124; Id  &#124; Operation        &#124; Name            &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
------------------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT &#124;                 &#124;    10 &#124;   250 &#124;    93   (2)&#124; 00:00:01 &#124;
&#124;*  1 &#124;  INDEX SKIP SCAN &#124; IND_T1_C1_C2_C3 &#124;    10 &#124;   250 &#124;    93   (2)&#124; 00:00:01 &#124;
------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access(&quot;C2&quot;&lt;10)
       filter(&quot;C2&quot;&lt;10)
[/sourcecode]
The optimizer selected the lowest cost access path from the two indexes that matched the hint.

What if we specify a column in the index hint that is not listed in the SELECT or WHERE clauses?
[sourcecode]
SELECT /*+ INDEX(T1 (C3)) */
  C1,
  C2
FROM
  T1
WHERE
  C2&lt;10;
 
Plan hash value: 1328421701
 
------------------------------------------------------------------------------------
&#124; Id  &#124; Operation        &#124; Name            &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
------------------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT &#124;                 &#124;    10 &#124;    90 &#124;  4039   (1)&#124; 00:00:02 &#124;
&#124;*  1 &#124;  INDEX SKIP SCAN &#124; IND_T1_C3_C1_C2 &#124;    10 &#124;    90 &#124;  4039   (1)&#124; 00:00:02 &#124;
------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access(&quot;C2&quot;&lt;10)
       filter(&quot;C2&quot;&lt;10)
[/sourcecode]
The above shows that the optimizer still obeyed the intention of the hint - it found an index that started with the specified column and selected to perform an INDEX SKIP SCAN even though column C2, specified in the WHERE clause, is the third column in the index definition.

What happens if we try something silly by modifying the WHERE clause in the previous SQL statement to specify that essentially every row from the table will be retrieved:
[sourcecode]
SELECT /*+ INDEX(T1 (C3)) */
  C1,
  C2
FROM
  T1
WHERE
  C2&lt;1000000;
 
Plan hash value: 1328421701
 
------------------------------------------------------------------------------------
&#124; Id  &#124; Operation        &#124; Name            &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
------------------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT &#124;                 &#124;  1000K&#124;  8789K&#124;  5283   (6)&#124; 00:00:03 &#124;
&#124;*  1 &#124;  INDEX SKIP SCAN &#124; IND_T1_C3_C1_C2 &#124;  1000K&#124;  8789K&#124;  5283   (6)&#124; 00:00:03 &#124;
------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access(&quot;C2&quot;&lt;1000000)
       filter(&quot;C2&quot;&lt;1000000)
[/sourcecode]

At least with B*tree indexes and simple SQL statements, there do not appear to be any edge cases, although specifying an invalid index hint might appear to be an edge case at first glance.]]></description>
		<content:encoded><![CDATA[<p>For what it is worth, I was not successful in disproving what you stated when testing Oracle Database 11.2.0.2 (although it is possible to make it appear as though what is stated is incorrect, simply by using an invalid index hint).  The test table and indexes that I started with were defined as follows:</p>
<pre class="brush: plain; title: ; notranslate">
CREATE TABLE T1 (
  C1 NUMBER NOT NULL,
  C2 NUMBER NOT NULL,
  C3 VARCHAR2(30) NOT NULL,
  C4 VARCHAR2(200));
 
INSERT INTO T1
SELECT
  MOD(ROWNUM-1, 90) * 4 C1,
  ROWNUM - 1 C2,
  TO_CHAR(ROWNUM - 1, 'RN') C3,
  LPAD('A',200,'A') C4
FROM
  DUAL
CONNECT BY
  LEVEL&lt;=1000000;
 
CREATE INDEX IND_T1_C1_C2 ON T1(C1,C2);
CREATE INDEX IND_T1_C2_C1_C3 ON T1(C2,C1,C3);
CREATE INDEX IND_T1_C3_C1_C2 ON T1(C3,C1,C2);
 
EXEC DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=&gt;USER,TABNAME=&gt;'T1',CASCADE=&gt;TRUE)
 
SET AUTOTRACE TRACEONLY EXPLAIN
SET LINESIZE 120
SET PAGESIZE 1000
</pre>
<p>Unhinted, the following query accesses the index on columns C2, C1, and C3 to avoid accessing the table:</p>
<pre class="brush: plain; title: ; notranslate">
SELECT
  C1,
  C2,
  C3
FROM
  T1;
 
Plan hash value: 2374279026
 
----------------------------------------------------------------------------------------
| Id  | Operation            | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |                 |  1000K|    23M|  1823  (11)| 00:00:01 |
|   1 |  INDEX FAST FULL SCAN| IND_T1_C2_C1_C3 |  1000K|    23M|  1823  (11)| 00:00:01 |
----------------------------------------------------------------------------------------
</pre>
<p>Let&#8217;s hint the optimizer to use the index on the columns C1 and C2:</p>
<pre class="brush: plain; title: ; notranslate"> 
SELECT /*+ INDEX(T1 (C1 C2)) */
  C1,
  C2,
  C3
FROM
  T1;
 
Plan hash value: 3388050039
 
--------------------------------------------------------------------------------------------
| Id  | Operation                   | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |              |  1000K|    23M|  1012K  (1)| 00:06:46 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T1           |  1000K|    23M|  1012K  (1)| 00:06:46 |
|   2 |   INDEX FULL SCAN           | IND_T1_C1_C2 |  1000K|       |  3026  (10)| 00:00:02 |
--------------------------------------------------------------------------------------------
</pre>
<p>In the above, the optimizer obeyed the hint, even though the calculated cost from the unhinted plan increased from 1,823 to 1,012,000.</p>
<p>Let&#8217;s reverse the order of the columns in the index hint:</p>
<pre class="brush: plain; title: ; notranslate">
SELECT /*+ INDEX(T1 (C2 C1)) */
  C1,
  C2,
  C3
FROM
  T1;
 
----------------------------------------------------------
Plan hash value: 1746297295

------------------------------------------------------------------------------------
| Id  | Operation        | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |                 |  1000K|    23M|  5171   (6)| 00:00:03 |
|   1 |  INDEX FULL SCAN | IND_T1_C2_C1_C3 |  1000K|    23M|  5171   (6)| 00:00:03 |
------------------------------------------------------------------------------------
</pre>
<p>In the above, note that the index on columns C2, C1, and C3 was used, but the cost is now calculated at 5,171 rather than 1,823 as it was in the unhinted plan.  The INDEX FAST FULL SCAN operation is now shown as an INDEX FULL SCAN operation.</p>
<p>We have an index on columns C2, C1, and C3, but we also have an index on columns C3, c1, and C2.  What happens when we specify the columns C3, C1, and C2 in the index hint in that order?</p>
<pre class="brush: plain; title: ; notranslate">
SELECT /*+ INDEX(T1 (C3 C1 C2)) */
  C1,
  C2,
  C3
FROM
  T1;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 2273443829
 
------------------------------------------------------------------------------------
| Id  | Operation        | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |                 |  1000K|    23M|  5283   (6)| 00:00:03 |
|   1 |  INDEX FULL SCAN | IND_T1_C3_C1_C2 |  1000K|    23M|  5283   (6)| 00:00:03 |
------------------------------------------------------------------------------------
</pre>
<p>An index full scan was selected to performed on the IND_T1_C3_C1_C2 index at a cost 5,283, rather than using the IND_T1_C2_C1_C3 index that previously resulted in a cost of 5,171 &#8211; so the optimizer will not alter the order of the columns in the index hint to reduce the calculated cost.</p>
<p>If we add a WHERE clause that places a restriction on column C2 to be less than 10, the optimizer could use a couple of different access paths.  Let&#8217;s specify the columns C1 and C2 in the index hint to see which index is selected:</p>
<pre class="brush: plain; title: ; notranslate">
SELECT /*+ INDEX(T1 (C1 C2)) */
  C1,
  C2,
  C3
FROM
  T1
WHERE
  C2&lt;10;
 
Plan hash value: 1883798457
 
--------------------------------------------------------------------------------------------
| Id  | Operation                   | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |              |    10 |   250 |   104   (1)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T1           |    10 |   250 |   104   (1)| 00:00:01 |
|*  2 |   INDEX SKIP SCAN           | IND_T1_C1_C2 |    10 |       |    93   (2)| 00:00:01 |
--------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access(&quot;C2&quot;&lt;10)
       filter(&quot;C2&quot;&lt;10)
</pre>
<p>In the above, a skip scan was selected because the index with columns C1 and C2 was specified in the hint.</p>
<p>Let&#8217;s try another example that possibly might be considered a case where the optimizer disobeys the hint or is free to change the order of the columns specified in the index hint (this might be incorrectly considered an edge case):</p>
<pre class="brush: plain; title: ; notranslate">
SELECT /*+ INDEX(T1 (C1 C2 C3)) */
  C1,
  C2,
  C3
FROM
  T1
WHERE
  C2&lt;10;
  
Plan hash value: 4150417361
 
------------------------------------------------------------------------------------
| Id  | Operation        | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |                 |    10 |   250 |     3   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| IND_T1_C2_C1_C3 |    10 |   250 |     3   (0)| 00:00:01 |
------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access(&quot;C2&quot;&lt;10)
</pre>
<p>A quick peek at the above output might suggest that the optimizer could decide to locate an index with columns C1, C2, and C3 in any order &#8211; but I do not believe that this is the case.  I believe that the optimizer considered the index hint specified in the SQL statement as being invalid (a check of the 10053 trace might confirm).</p>
<p>Let&#8217;s create another index and then repeat the above SQL statement.</p>
<pre class="brush: plain; title: ; notranslate">
CREATE INDEX IND_T1_C1_C2_C3 ON T1(C1,C2,C3);
 
SELECT /*+ INDEX(T1 (C1 C2 C3)) */
  C1,
  C2,
  C3
FROM
  T1
WHERE
  C2&lt;10;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 212907557
 
------------------------------------------------------------------------------------
| Id  | Operation        | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |                 |    10 |   250 |    93   (2)| 00:00:01 |
|*  1 |  INDEX SKIP SCAN | IND_T1_C1_C2_C3 |    10 |   250 |    93   (2)| 00:00:01 |
------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access(&quot;C2&quot;&lt;10)
       filter(&quot;C2&quot;&lt;10)
</pre>
<p>The index with the columns that matched the order of the columns in the index hint was selected, even though the calculated cost would have been lower if the optimizer were permitted to select any index with the columns listed in the index hint.</p>
<p>What about a case where there is an exact match between an index definition and an index hint, and there is also another index with one additional column which would avoid the table access:</p>
<pre class="brush: plain; title: ; notranslate">
SELECT /*+ INDEX(T1 (C1 C2)) */
  C1,
  C2,
  C3
FROM
  T1
WHERE
  C2&lt;10;
 
Plan hash value: 1883798457
 
--------------------------------------------------------------------------------------------
| Id  | Operation                   | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |              |    10 |   250 |   104   (1)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T1           |    10 |   250 |   104   (1)| 00:00:01 |
|*  2 |   INDEX SKIP SCAN           | IND_T1_C1_C2 |    10 |       |    93   (2)| 00:00:01 |
--------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access(&quot;C2&quot;&lt;10)
       filter(&quot;C2&quot;&lt;10)
</pre>
<p>The index that exactly match the index hint was selected.</p>
<p>What if we only specify in the index hint a leading column, when there are two indexes with that leading column, one of which allows the optimizer to avoid the table access:</p>
<pre class="brush: plain; title: ; notranslate"> 
SELECT /*+ INDEX(T1 (C1)) */
  C1,
  C2,
  C3
FROM
  T1
WHERE
  C2&lt;10;
 
Plan hash value: 212907557
 
------------------------------------------------------------------------------------
| Id  | Operation        | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |                 |    10 |   250 |    93   (2)| 00:00:01 |
|*  1 |  INDEX SKIP SCAN | IND_T1_C1_C2_C3 |    10 |   250 |    93   (2)| 00:00:01 |
------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access(&quot;C2&quot;&lt;10)
       filter(&quot;C2&quot;&lt;10)
</pre>
<p>The optimizer selected the lowest cost access path from the two indexes that matched the hint.</p>
<p>What if we specify a column in the index hint that is not listed in the SELECT or WHERE clauses?</p>
<pre class="brush: plain; title: ; notranslate">
SELECT /*+ INDEX(T1 (C3)) */
  C1,
  C2
FROM
  T1
WHERE
  C2&lt;10;
 
Plan hash value: 1328421701
 
------------------------------------------------------------------------------------
| Id  | Operation        | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |                 |    10 |    90 |  4039   (1)| 00:00:02 |
|*  1 |  INDEX SKIP SCAN | IND_T1_C3_C1_C2 |    10 |    90 |  4039   (1)| 00:00:02 |
------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access(&quot;C2&quot;&lt;10)
       filter(&quot;C2&quot;&lt;10)
</pre>
<p>The above shows that the optimizer still obeyed the intention of the hint &#8211; it found an index that started with the specified column and selected to perform an INDEX SKIP SCAN even though column C2, specified in the WHERE clause, is the third column in the index definition.</p>
<p>What happens if we try something silly by modifying the WHERE clause in the previous SQL statement to specify that essentially every row from the table will be retrieved:</p>
<pre class="brush: plain; title: ; notranslate">
SELECT /*+ INDEX(T1 (C3)) */
  C1,
  C2
FROM
  T1
WHERE
  C2&lt;1000000;
 
Plan hash value: 1328421701
 
------------------------------------------------------------------------------------
| Id  | Operation        | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |                 |  1000K|  8789K|  5283   (6)| 00:00:03 |
|*  1 |  INDEX SKIP SCAN | IND_T1_C3_C1_C2 |  1000K|  8789K|  5283   (6)| 00:00:03 |
------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access(&quot;C2&quot;&lt;1000000)
       filter(&quot;C2&quot;&lt;1000000)
</pre>
<p>At least with B*tree indexes and simple SQL statements, there do not appear to be any edge cases, although specifying an invalid index hint might appear to be an edge case at first glance.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Valentin Nikotin</title>
		<link>http://jonathanlewis.wordpress.com/2012/01/13/quiz-night-15/#comment-44439</link>
		<dc:creator><![CDATA[Valentin Nikotin]]></dc:creator>
		<pubDate>Sun, 15 Jan 2012 15:52:33 +0000</pubDate>
		<guid isPermaLink="false">http://jonathanlewis.wordpress.com/?p=8101#comment-44439</guid>
		<description><![CDATA[The Optimizer transforms the hint to /*+ INDEX (&quot;T&quot; &quot;IND&quot;) */ while it performs.
After that it will consider all indexes having the same name.

[sourcecode language=&quot;SQL&quot; collapse=&quot;true&quot;]SQL&gt; create user u1 identified by u1 quota unlimited on users;

User created.

SQL&gt; create user u2 identified by u2 quota unlimited on users;

User created.

SQL&gt; create table u1.abc(a int not null, b int, c int);

Table created.

SQL&gt; create index u1.ind on u1.abc (a, b);

Index created.

SQL&gt; create index u2.ind on u1.abc (a, b, c);

Index created.

SQL&gt; insert into u1.abc select level, level, level from dual connect by level &lt; 1e5;

99999 rows created.

SQL&gt; commit;

Commit complete.

SQL&gt; exec dbms_stats.gather_table_stats(&#039;u1&#039;,&#039;abc&#039;);

PL/SQL procedure successfully completed.

SQL&gt; explain plan for select /*+ index(t(a, b))*/ * from u1.abc t;

Explained.

SQL&gt; select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 1202921093

-------------------------------------------------------------------------
&#124; Id  &#124; Operation        &#124; Name &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
-------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT &#124;      &#124; 99999 &#124;  1464K&#124;   323   (1)&#124; 00:00:04 &#124;
&#124;   1 &#124;  INDEX FULL SCAN &#124; IND  &#124; 99999 &#124;  1464K&#124;   323   (1)&#124; 00:00:04 &#124;
-------------------------------------------------------------------------

8 rows selected.[/sourcecode]]]></description>
		<content:encoded><![CDATA[<p>The Optimizer transforms the hint to /*+ INDEX (&#8220;T&#8221; &#8220;IND&#8221;) */ while it performs.<br />
After that it will consider all indexes having the same name.</p>
<pre class="brush: sql; collapse: true; light: false; title: ; toolbar: true; notranslate">SQL&gt; create user u1 identified by u1 quota unlimited on users;

User created.

SQL&gt; create user u2 identified by u2 quota unlimited on users;

User created.

SQL&gt; create table u1.abc(a int not null, b int, c int);

Table created.

SQL&gt; create index u1.ind on u1.abc (a, b);

Index created.

SQL&gt; create index u2.ind on u1.abc (a, b, c);

Index created.

SQL&gt; insert into u1.abc select level, level, level from dual connect by level &lt; 1e5;

99999 rows created.

SQL&gt; commit;

Commit complete.

SQL&gt; exec dbms_stats.gather_table_stats('u1','abc');

PL/SQL procedure successfully completed.

SQL&gt; explain plan for select /*+ index(t(a, b))*/ * from u1.abc t;

Explained.

SQL&gt; select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 1202921093

-------------------------------------------------------------------------
| Id  | Operation        | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------
|   0 | SELECT STATEMENT |      | 99999 |  1464K|   323   (1)| 00:00:04 |
|   1 |  INDEX FULL SCAN | IND  | 99999 |  1464K|   323   (1)| 00:00:04 |
-------------------------------------------------------------------------

8 rows selected.</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Mohamed Houri</title>
		<link>http://jonathanlewis.wordpress.com/2012/01/13/quiz-night-15/#comment-44430</link>
		<dc:creator><![CDATA[Mohamed Houri]]></dc:creator>
		<pubDate>Sun, 15 Jan 2012 09:17:36 +0000</pubDate>
		<guid isPermaLink="false">http://jonathanlewis.wordpress.com/?p=8101#comment-44430</guid>
		<description><![CDATA[If you select  product_group, id, other_col, in totality or not (but at most only those columns) and you hint to use the two columns index (product_group, id) for a query involving in its where clause only a predicate on other_col then the CBO might(depending on your data and how it is scattered) do an index FFS  on the 3 columns  index instead of the hinted 2 columns index]]></description>
		<content:encoded><![CDATA[<p>If you select  product_group, id, other_col, in totality or not (but at most only those columns) and you hint to use the two columns index (product_group, id) for a query involving in its where clause only a predicate on other_col then the CBO might(depending on your data and how it is scattered) do an index FFS  on the 3 columns  index instead of the hinted 2 columns index</p>
]]></content:encoded>
	</item>
</channel>
</rss>
