<?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: Test Case Showing Oracle Database 11.2.0.1 Completely Ignoring an Index Even when Hinted</title>
	<atom:link href="http://hoopercharles.wordpress.com/2010/09/22/test-case-showing-oracle-database-11-2-0-1-completely-ignoring-an-index-even-when-hinted/feed/" rel="self" type="application/rss+xml" />
	<link>http://hoopercharles.wordpress.com/2010/09/22/test-case-showing-oracle-database-11-2-0-1-completely-ignoring-an-index-even-when-hinted/</link>
	<description>Miscellaneous Random Oracle Topics: Stop, Think, ... Understand</description>
	<lastBuildDate>Mon, 13 May 2013 14:10:06 +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/2010/09/22/test-case-showing-oracle-database-11-2-0-1-completely-ignoring-an-index-even-when-hinted/#comment-1879</link>
		<dc:creator><![CDATA[Charles Hooper]]></dc:creator>
		<pubDate>Wed, 22 Sep 2010 19:21:57 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=3349#comment-1879</guid>
		<description><![CDATA[Randolf Geist demonstrated in the OTN thread that the OP&#039;s table definition is probably missing a NOT NULL constraint.  Randolf was able to generate an execution plan with a NOT NULL constraint on the C200000020 column when an index hint was also provided.  Randolf used a slightly different test case, so I have adapted his test case to work with my sample table.  Let&#039;s take a look at the execution plans:
[code]
ALTER TABLE T1 MODIFY (C200000020 NOT NULL);
ALTER SYSTEM FLUSH SHARED_POOL;
 
SET AUTOTRACE TRACEONLY EXPLAIN
 
SELECT
  *
FROM
  T1
WHERE
  C200000020 LIKE &#039;BOSS&#039; &#124;&#124; &#039;%&#039;
  OR &#039;BOSS&#039; = &#039;&#039;;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 3617692013
 
--------------------------------------------------------------------------
&#124; Id  &#124; Operation         &#124; Name &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
--------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT  &#124;      &#124;   100K&#124;    20M&#124; 82353   (1)&#124; 00:16:29 &#124;
&#124;*  1 &#124;  TABLE ACCESS FULL&#124; T1   &#124;   100K&#124;    20M&#124; 82353   (1)&#124; 00:16:29 &#124;
--------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter(&#039;BOSS&#039;=&#039;&#039; OR &quot;C200000020&quot; LIKE &#039;BOSS%&#039;)
[/code]
Without an index hint the optimizer still selected to perform a full table scan.

Now with the index hint:
[code]
SELECT /*+ INDEX(T1 IND_T1) */
  *
FROM
  T1
WHERE
  C200000020 LIKE &#039;BOSS&#039; &#124;&#124; &#039;%&#039;
  OR &#039;BOSS&#039; = &#039;&#039;;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 3418867520
 
--------------------------------------------------------------------------------------
&#124; Id  &#124; Operation                   &#124; Name   &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
--------------------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT            &#124;        &#124;   100K&#124;    20M&#124;  9980K  (1)&#124; 33:16:04 &#124;
&#124;*  1 &#124;  TABLE ACCESS BY INDEX ROWID&#124; T1     &#124;   100K&#124;    20M&#124;  9980K  (1)&#124; 33:16:04 &#124;
&#124;   2 &#124;   INDEX FULL SCAN           &#124; IND_T1 &#124;    10M&#124;       &#124; 31855   (1)&#124; 00:06:23 &#124;
--------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter(&#039;BOSS&#039;=&#039;&#039; OR &quot;C200000020&quot; LIKE &#039;BOSS%&#039;)
[/code]
An index full scan, so we are using the index now.  But look at the estimated time - it jumped from just 16 minutes to 33 hours and 16 minutes!

Let&#039;s test the performance (your results will be different):
[code]
SET AUTOTRACE OFF
SET TIMING ON
 
ALTER SYSTEM FLUSH BUFFER_CACHE;
ALTER SYSTEM FLUSH BUFFER_CACHE;
 
SELECT
  *
FROM
  T1
WHERE
  C200000020 LIKE &#039;BOSS&#039; &#124;&#124; &#039;%&#039;
  OR &#039;BOSS&#039; = &#039;&#039;;
 
ALTER SYSTEM FLUSH BUFFER_CACHE;
ALTER SYSTEM FLUSH BUFFER_CACHE;
 
SELECT /*+ INDEX(T1 IND_T1) */
  *
FROM
  T1
WHERE
  C200000020 LIKE &#039;BOSS&#039; &#124;&#124; &#039;%&#039;
  OR &#039;BOSS&#039; = &#039;&#039;;
 
ALTER SYSTEM FLUSH BUFFER_CACHE;
ALTER SYSTEM FLUSH BUFFER_CACHE;
 
SELECT /*+ INDEX(T1 IND_T1) */
  *
FROM
  T1
WHERE
  C200000020 LIKE &#039;BOSS&#039; &#124;&#124; &#039;%&#039;;
[/code]

The results that I received follow:
[code]
SQL&gt; SELECT
  2    *
  3  FROM
  4    T1
  5  WHERE
  6    C200000020 LIKE &#039;BOSS&#039; &#124;&#124; &#039;%&#039;
  7    OR &#039;BOSS&#039; = &#039;&#039;;
 
C200000020
--------------------
PADDING
---------------------------------------
BOSS3000000
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

BOSS6000000
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

BOSS9000000
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


Elapsed: 00:00:04.49
SQL&gt;
SQL&gt; ALTER SYSTEM FLUSH BUFFER_CACHE;

System altered.

Elapsed: 00:00:00.06
SQL&gt; ALTER SYSTEM FLUSH BUFFER_CACHE;

System altered.

Elapsed: 00:00:00.06
SQL&gt;
SQL&gt; SELECT /*+ INDEX(T1 IND_T1) */
  2    *
  3  FROM
  4    T1
  5  WHERE
  6    C200000020 LIKE &#039;BOSS&#039; &#124;&#124; &#039;%&#039;
  7    OR &#039;BOSS&#039; = &#039;&#039;;

C200000020
--------------------
PADDING
---------------------------------------
BOSS3000000
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

BOSS6000000
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

BOSS9000000
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


Elapsed: 00:02:32.81
SQL&gt; ALTER SYSTEM FLUSH BUFFER_CACHE;

System altered.

Elapsed: 00:00:00.15
SQL&gt; ALTER SYSTEM FLUSH BUFFER_CACHE;

System altered.

Elapsed: 00:00:00.09
SQL&gt;
SQL&gt; SELECT /*+ INDEX(T1 IND_T1) */
  2    *
  3  FROM
  4    T1
  5  WHERE
  6    C200000020 LIKE &#039;BOSS&#039; &#124;&#124; &#039;%&#039;;

C200000020
--------------------
PADDING
---------------------------------------
BOSS3000000
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

BOSS6000000
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

BOSS9000000
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


Elapsed: 00:00:00.07
[/code]

4.49 seconds to perform the full table scan, 2 minutes and 32.81 seconds for the index full scan, and 0.07 seconds to do it the correct way.

The table and index extent sizes follow:
[code]
SELECT
  SEGMENT_NAME SEGMENT,
  COUNT(*) EXTENTS,
  BYTES/1024 EXT_SIZE_KB,
  (COUNT(*) * BYTES)/1048576 TOTAL_MB
FROM
  DBA_EXTENTS
WHERE
  OWNER=USER
  AND SEGMENT_NAME IN (&#039;IND_T1&#039;,&#039;T1&#039;)
GROUP BY
  SEGMENT_NAME,
  BYTES
ORDER BY
  SEGMENT_NAME,
  BYTES;
 
SEGMENT       EXTENTS EXT_SIZE_KB   TOTAL_MB
---------- ---------- ----------- ----------
IND_T1             16          64          1
IND_T1             63        1024         63
IND_T1             24        8192        192
T1                 16          64          1
T1                 63        1024         63
T1                120        8192        960
T1                 21       65536       1344
[/code]]]></description>
		<content:encoded><![CDATA[<p>Randolf Geist demonstrated in the OTN thread that the OP&#8217;s table definition is probably missing a NOT NULL constraint.  Randolf was able to generate an execution plan with a NOT NULL constraint on the C200000020 column when an index hint was also provided.  Randolf used a slightly different test case, so I have adapted his test case to work with my sample table.  Let&#8217;s take a look at the execution plans:</p>
<pre class="brush: plain; title: ; notranslate">
ALTER TABLE T1 MODIFY (C200000020 NOT NULL);
ALTER SYSTEM FLUSH SHARED_POOL;
 
SET AUTOTRACE TRACEONLY EXPLAIN
 
SELECT
  *
FROM
  T1
WHERE
  C200000020 LIKE 'BOSS' || '%'
  OR 'BOSS' = '';
 
Execution Plan
----------------------------------------------------------
Plan hash value: 3617692013
 
--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |   100K|    20M| 82353   (1)| 00:16:29 |
|*  1 |  TABLE ACCESS FULL| T1   |   100K|    20M| 82353   (1)| 00:16:29 |
--------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter('BOSS'='' OR &quot;C200000020&quot; LIKE 'BOSS%')
</pre>
<p>Without an index hint the optimizer still selected to perform a full table scan.</p>
<p>Now with the index hint:</p>
<pre class="brush: plain; title: ; notranslate">
SELECT /*+ INDEX(T1 IND_T1) */
  *
FROM
  T1
WHERE
  C200000020 LIKE 'BOSS' || '%'
  OR 'BOSS' = '';
 
Execution Plan
----------------------------------------------------------
Plan hash value: 3418867520
 
--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |   100K|    20M|  9980K  (1)| 33:16:04 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| T1     |   100K|    20M|  9980K  (1)| 33:16:04 |
|   2 |   INDEX FULL SCAN           | IND_T1 |    10M|       | 31855   (1)| 00:06:23 |
--------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter('BOSS'='' OR &quot;C200000020&quot; LIKE 'BOSS%')
</pre>
<p>An index full scan, so we are using the index now.  But look at the estimated time &#8211; it jumped from just 16 minutes to 33 hours and 16 minutes!</p>
<p>Let&#8217;s test the performance (your results will be different):</p>
<pre class="brush: plain; title: ; notranslate">
SET AUTOTRACE OFF
SET TIMING ON
 
ALTER SYSTEM FLUSH BUFFER_CACHE;
ALTER SYSTEM FLUSH BUFFER_CACHE;
 
SELECT
  *
FROM
  T1
WHERE
  C200000020 LIKE 'BOSS' || '%'
  OR 'BOSS' = '';
 
ALTER SYSTEM FLUSH BUFFER_CACHE;
ALTER SYSTEM FLUSH BUFFER_CACHE;
 
SELECT /*+ INDEX(T1 IND_T1) */
  *
FROM
  T1
WHERE
  C200000020 LIKE 'BOSS' || '%'
  OR 'BOSS' = '';
 
ALTER SYSTEM FLUSH BUFFER_CACHE;
ALTER SYSTEM FLUSH BUFFER_CACHE;
 
SELECT /*+ INDEX(T1 IND_T1) */
  *
FROM
  T1
WHERE
  C200000020 LIKE 'BOSS' || '%';
</pre>
<p>The results that I received follow:</p>
<pre class="brush: plain; title: ; notranslate">
SQL&gt; SELECT
  2    *
  3  FROM
  4    T1
  5  WHERE
  6    C200000020 LIKE 'BOSS' || '%'
  7    OR 'BOSS' = '';
 
C200000020
--------------------
PADDING
---------------------------------------
BOSS3000000
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

BOSS6000000
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

BOSS9000000
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


Elapsed: 00:00:04.49
SQL&gt;
SQL&gt; ALTER SYSTEM FLUSH BUFFER_CACHE;

System altered.

Elapsed: 00:00:00.06
SQL&gt; ALTER SYSTEM FLUSH BUFFER_CACHE;

System altered.

Elapsed: 00:00:00.06
SQL&gt;
SQL&gt; SELECT /*+ INDEX(T1 IND_T1) */
  2    *
  3  FROM
  4    T1
  5  WHERE
  6    C200000020 LIKE 'BOSS' || '%'
  7    OR 'BOSS' = '';

C200000020
--------------------
PADDING
---------------------------------------
BOSS3000000
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

BOSS6000000
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

BOSS9000000
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


Elapsed: 00:02:32.81
SQL&gt; ALTER SYSTEM FLUSH BUFFER_CACHE;

System altered.

Elapsed: 00:00:00.15
SQL&gt; ALTER SYSTEM FLUSH BUFFER_CACHE;

System altered.

Elapsed: 00:00:00.09
SQL&gt;
SQL&gt; SELECT /*+ INDEX(T1 IND_T1) */
  2    *
  3  FROM
  4    T1
  5  WHERE
  6    C200000020 LIKE 'BOSS' || '%';

C200000020
--------------------
PADDING
---------------------------------------
BOSS3000000
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

BOSS6000000
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

BOSS9000000
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


Elapsed: 00:00:00.07
</pre>
<p>4.49 seconds to perform the full table scan, 2 minutes and 32.81 seconds for the index full scan, and 0.07 seconds to do it the correct way.</p>
<p>The table and index extent sizes follow:</p>
<pre class="brush: plain; title: ; notranslate">
SELECT
  SEGMENT_NAME SEGMENT,
  COUNT(*) EXTENTS,
  BYTES/1024 EXT_SIZE_KB,
  (COUNT(*) * BYTES)/1048576 TOTAL_MB
FROM
  DBA_EXTENTS
WHERE
  OWNER=USER
  AND SEGMENT_NAME IN ('IND_T1','T1')
GROUP BY
  SEGMENT_NAME,
  BYTES
ORDER BY
  SEGMENT_NAME,
  BYTES;
 
SEGMENT       EXTENTS EXT_SIZE_KB   TOTAL_MB
---------- ---------- ----------- ----------
IND_T1             16          64          1
IND_T1             63        1024         63
IND_T1             24        8192        192
T1                 16          64          1
T1                 63        1024         63
T1                120        8192        960
T1                 21       65536       1344
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Charles Hooper</title>
		<link>http://hoopercharles.wordpress.com/2010/09/22/test-case-showing-oracle-database-11-2-0-1-completely-ignoring-an-index-even-when-hinted/#comment-1873</link>
		<dc:creator><![CDATA[Charles Hooper]]></dc:creator>
		<pubDate>Wed, 22 Sep 2010 14:50:13 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=3349#comment-1873</guid>
		<description><![CDATA[In my opinion, if &#039;&#039; is treated as NULL, the second half of the OR clause should always be false, because nothing is ever equal to NULL, not even NULL.  I agree with you that with the bind variables, the second half of the OR clause *could* be true, even if it cannot be true on the initial hard parse - a full table scan should be expected in that case.

Before running the tests, I would assume that ‘BOSS’ = ‘SUPERCALIFRAGILISTICEXPEALIDOCIOUS’ should be handled the same as the case where I used a single space between the two &#039; characters.  Here are the test results:
[code]
SET AUTOTRACE TRACEONLY EXPLAIN
 
SELECT
  *
FROM
  T1
WHERE
  C200000020 LIKE &#039;BOSS&#039; &#124;&#124; &#039;%&#039;
  OR &#039;BOSS&#039; = &#039;SUPERCALIFRAGILISTICEXPEALIDOCIOUS&#039;;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 634656657
 
--------------------------------------------------------------------------------------
&#124; Id  &#124; Operation                   &#124; Name   &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
--------------------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT            &#124;        &#124;     1 &#124;   213 &#124;     5   (0)&#124; 00:00:01 &#124;
&#124;   1 &#124;  TABLE ACCESS BY INDEX ROWID&#124; T1     &#124;     1 &#124;   213 &#124;     5   (0)&#124; 00:00:01 &#124;
&#124;*  2 &#124;   INDEX RANGE SCAN          &#124; IND_T1 &#124;     1 &#124;       &#124;     3   (0)&#124; 00:00:01 &#124;
--------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access(&quot;C200000020&quot; LIKE &#039;BOSS%&#039;)
       filter(&quot;C200000020&quot; LIKE &#039;BOSS%&#039;)
[/code]
Above used an index range scan, as would be expected.

[code]
SELECT
  *
FROM
  T1
WHERE
  C200000020 LIKE &#039;BOSS&#039; &#124;&#124; &#039;%&#039;
  OR &#039;BOSS&#039; = NULL;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 634656657
 
--------------------------------------------------------------------------------------
&#124; Id  &#124; Operation                   &#124; Name   &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
--------------------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT            &#124;        &#124;     1 &#124;   213 &#124;     5   (0)&#124; 00:00:01 &#124;
&#124;   1 &#124;  TABLE ACCESS BY INDEX ROWID&#124; T1     &#124;     1 &#124;   213 &#124;     5   (0)&#124; 00:00:01 &#124;
&#124;*  2 &#124;   INDEX RANGE SCAN          &#124; IND_T1 &#124;     1 &#124;       &#124;     3   (0)&#124; 00:00:01 &#124;
--------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access(&quot;C200000020&quot; LIKE &#039;BOSS%&#039;)
       filter(&quot;C200000020&quot; LIKE &#039;BOSS%&#039;)
[/code]
Above used an index range scan, as would be expected.

[code]
SELECT
  *
FROM
  T1
WHERE
  C200000020 LIKE &#039;BOSS&#039; &#124;&#124; &#039;%&#039;
  OR &#039;BOSS&#039; IS NULL;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 634656657
 
--------------------------------------------------------------------------------------
&#124; Id  &#124; Operation                   &#124; Name   &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
--------------------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT            &#124;        &#124;     1 &#124;   213 &#124;     5   (0)&#124; 00:00:01 &#124;
&#124;   1 &#124;  TABLE ACCESS BY INDEX ROWID&#124; T1     &#124;     1 &#124;   213 &#124;     5   (0)&#124; 00:00:01 &#124;
&#124;*  2 &#124;   INDEX RANGE SCAN          &#124; IND_T1 &#124;     1 &#124;       &#124;     3   (0)&#124; 00:00:01 &#124;
--------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access(&quot;C200000020&quot; LIKE &#039;BOSS%&#039;)
       filter(&quot;C200000020&quot; LIKE &#039;BOSS%&#039;)
[/code]
Above used an index range scan, as would be expected.

[code]
SELECT
  *
FROM
  T1
WHERE
  C200000020 LIKE &#039;BOSS&#039; &#124;&#124; &#039;%&#039;
  OR &#039;BOSS&#039; = &#039; &#039;;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 634656657
 
--------------------------------------------------------------------------------------
&#124; Id  &#124; Operation                   &#124; Name   &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
--------------------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT            &#124;        &#124;     1 &#124;   213 &#124;     5   (0)&#124; 00:00:01 &#124;
&#124;   1 &#124;  TABLE ACCESS BY INDEX ROWID&#124; T1     &#124;     1 &#124;   213 &#124;     5   (0)&#124; 00:00:01 &#124;
&#124;*  2 &#124;   INDEX RANGE SCAN          &#124; IND_T1 &#124;     1 &#124;       &#124;     3   (0)&#124; 00:00:01 &#124;
--------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access(&quot;C200000020&quot; LIKE &#039;BOSS%&#039;)
       filter(&quot;C200000020&quot; LIKE &#039;BOSS%&#039;)
[/code]
Above used an index range scan, as would be expected.

[code]
SELECT
  *
FROM
  T1
WHERE
  C200000020 LIKE &#039;BOSS&#039; &#124;&#124; &#039;%&#039;
  OR &#039;BOSS&#039; = &#039;&#039;;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 3617692013
 
--------------------------------------------------------------------------
&#124; Id  &#124; Operation         &#124; Name &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
--------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT  &#124;      &#124;   100K&#124;    20M&#124; 82353   (1)&#124; 00:16:29 &#124;
&#124;*  1 &#124;  TABLE ACCESS FULL&#124; T1   &#124;   100K&#124;    20M&#124; 82353   (1)&#124; 00:16:29 &#124;
--------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter(&#039;BOSS&#039;=&#039;&#039; OR &quot;C200000020&quot; LIKE &#039;BOSS%&#039;)
[/code]

The above used a full table scan because the index access paths were not even considered.]]></description>
		<content:encoded><![CDATA[<p>In my opinion, if &#8221; is treated as NULL, the second half of the OR clause should always be false, because nothing is ever equal to NULL, not even NULL.  I agree with you that with the bind variables, the second half of the OR clause *could* be true, even if it cannot be true on the initial hard parse &#8211; a full table scan should be expected in that case.</p>
<p>Before running the tests, I would assume that ‘BOSS’ = ‘SUPERCALIFRAGILISTICEXPEALIDOCIOUS’ should be handled the same as the case where I used a single space between the two &#8216; characters.  Here are the test results:</p>
<pre class="brush: plain; title: ; notranslate">
SET AUTOTRACE TRACEONLY EXPLAIN
 
SELECT
  *
FROM
  T1
WHERE
  C200000020 LIKE 'BOSS' || '%'
  OR 'BOSS' = 'SUPERCALIFRAGILISTICEXPEALIDOCIOUS';
 
Execution Plan
----------------------------------------------------------
Plan hash value: 634656657
 
--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |     1 |   213 |     5   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T1     |     1 |   213 |     5   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IND_T1 |     1 |       |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access(&quot;C200000020&quot; LIKE 'BOSS%')
       filter(&quot;C200000020&quot; LIKE 'BOSS%')
</pre>
<p>Above used an index range scan, as would be expected.</p>
<pre class="brush: plain; title: ; notranslate">
SELECT
  *
FROM
  T1
WHERE
  C200000020 LIKE 'BOSS' || '%'
  OR 'BOSS' = NULL;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 634656657
 
--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |     1 |   213 |     5   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T1     |     1 |   213 |     5   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IND_T1 |     1 |       |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access(&quot;C200000020&quot; LIKE 'BOSS%')
       filter(&quot;C200000020&quot; LIKE 'BOSS%')
</pre>
<p>Above used an index range scan, as would be expected.</p>
<pre class="brush: plain; title: ; notranslate">
SELECT
  *
FROM
  T1
WHERE
  C200000020 LIKE 'BOSS' || '%'
  OR 'BOSS' IS NULL;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 634656657
 
--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |     1 |   213 |     5   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T1     |     1 |   213 |     5   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IND_T1 |     1 |       |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access(&quot;C200000020&quot; LIKE 'BOSS%')
       filter(&quot;C200000020&quot; LIKE 'BOSS%')
</pre>
<p>Above used an index range scan, as would be expected.</p>
<pre class="brush: plain; title: ; notranslate">
SELECT
  *
FROM
  T1
WHERE
  C200000020 LIKE 'BOSS' || '%'
  OR 'BOSS' = ' ';
 
Execution Plan
----------------------------------------------------------
Plan hash value: 634656657
 
--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |     1 |   213 |     5   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T1     |     1 |   213 |     5   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IND_T1 |     1 |       |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access(&quot;C200000020&quot; LIKE 'BOSS%')
       filter(&quot;C200000020&quot; LIKE 'BOSS%')
</pre>
<p>Above used an index range scan, as would be expected.</p>
<pre class="brush: plain; title: ; notranslate">
SELECT
  *
FROM
  T1
WHERE
  C200000020 LIKE 'BOSS' || '%'
  OR 'BOSS' = '';
 
Execution Plan
----------------------------------------------------------
Plan hash value: 3617692013
 
--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |   100K|    20M| 82353   (1)| 00:16:29 |
|*  1 |  TABLE ACCESS FULL| T1   |   100K|    20M| 82353   (1)| 00:16:29 |
--------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter('BOSS'='' OR &quot;C200000020&quot; LIKE 'BOSS%')
</pre>
<p>The above used a full table scan because the index access paths were not even considered.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: niall litchfield</title>
		<link>http://hoopercharles.wordpress.com/2010/09/22/test-case-showing-oracle-database-11-2-0-1-completely-ignoring-an-index-even-when-hinted/#comment-1871</link>
		<dc:creator><![CDATA[niall litchfield]]></dc:creator>
		<pubDate>Wed, 22 Sep 2010 13:23:01 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=3349#comment-1871</guid>
		<description><![CDATA[Charles, is this a null effect? I.E does the behavior reproduce with &#039;BOSS&#039;  = &#039;SUPERCALIFRAGILISTICEXPEALIDOCIOUS&#039;?  I agree that Oracle should know that a string of length 4 is not null, it wouldn&#039;t know that a bind was of course. Can&#039;t test right now]]></description>
		<content:encoded><![CDATA[<p>Charles, is this a null effect? I.E does the behavior reproduce with &#8216;BOSS&#8217;  = &#8216;SUPERCALIFRAGILISTICEXPEALIDOCIOUS&#8217;?  I agree that Oracle should know that a string of length 4 is not null, it wouldn&#8217;t know that a bind was of course. Can&#8217;t test right now</p>
]]></content:encoded>
	</item>
</channel>
</rss>
