<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress/2.6.5" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>
<channel>
	<title>Comments on: Using a Function-Based Index to &#8220;Avoid&#8221; a Sort</title>
	<link>http://www.pythian.com/blogs/580/using-a-function-based-index-to-avoid-a-sort</link>
	<description>News and views from Pythian DBAs</description>
	<pubDate>Fri,  5 Dec 2008 02:31:22 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.5</generator>
		<item>
		<title>By: Alex Fatkulin</title>
		<link>http://www.pythian.com/blogs/580/using-a-function-based-index-to-avoid-a-sort#comment-90364</link>
		<dc:creator>Alex Fatkulin</dc:creator>
		<pubDate>Tue, 28 Aug 2007 00:49:00 +0000</pubDate>
		<guid>http://www.pythian.com/blogs/580/using-a-function-based-index-to-avoid-a-sort#comment-90364</guid>
		<description>Amit,

that's a good news indeed. And yet another demonstration why it's always a good idea to verify things against new releases.</description>
		<content:encoded><![CDATA[<p>Amit,</p>
<p>that&#8217;s a good news indeed. And yet another demonstration why it&#8217;s always a good idea to verify things against new releases.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: amit poddar</title>
		<link>http://www.pythian.com/blogs/580/using-a-function-based-index-to-avoid-a-sort#comment-88502</link>
		<dc:creator>amit poddar</dc:creator>
		<pubDate>Fri, 24 Aug 2007 01:23:39 +0000</pubDate>
		<guid>http://www.pythian.com/blogs/580/using-a-function-based-index-to-avoid-a-sort#comment-88502</guid>
		<description>Hi,

Just for curiosity I tested in 11.1.0.6. In 11g it seems that we do not have to add the redundant expression into the order by clause. See below

SQL&#62;  create table requests ( subs_id  number(10), insert_time date, processed number(3));

Table created.

SQL&#62; create index fbi_requests_p 
  2  on requests
  3  (case processed when 0 then mod(subs_id, 7) end);

Index created.

SQL&#62; insert /*+ append */ into requests
  2     select trunc(dbms_random.value(0, 10000)),
  3            trunc(sysdate)+dbms_random.value(0, 1),
  4            case when rownum  commit;

Commit complete.

SQL&#62; exec dbms_stats.gather_table_stats(user, 'requests', cascade =&#62; true);

PL/SQL procedure successfully completed.

SQL&#62; select /*+ index(r fbi_requests_p) */ *
  from requests r
 where case processed when 0 then mod(subs_id, 7) end=:dequeue_process_number
   order by insert_time
  2    3    4    5  
SQL&#62; /

153 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 564389291

-----------------------------------------------------------------------------------------------
&#124; Id  &#124; Operation                    &#124; Name           &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
-----------------------------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT             &#124;                &#124;   143 &#124;  2145 &#124;     6  (17)&#124; 00:00:01 &#124;
&#124;   1 &#124;  SORT ORDER BY               &#124;                &#124;   143 &#124;  2145 &#124;     6  (17)&#124; 00:00:01 &#124;
&#124;   2 &#124;   TABLE ACCESS BY INDEX ROWID&#124; REQUESTS       &#124;   143 &#124;  2145 &#124;     5   (0)&#124; 00:00:01 &#124;
&#124;*  3 &#124;    INDEX RANGE SCAN          &#124; FBI_REQUESTS_P &#124;   143 &#124;       &#124;     1   (0)&#124; 00:00:01 &#124;
-----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - access(CASE "PROCESSED" WHEN 0 THEN MOD("SUBS_ID",7) END
              =TO_NUMBER(:DEQUEUE_PROCESS_NUMBER))


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          5  consistent gets
          0  physical reads
          0  redo size
       3278  bytes sent via SQL*Net to client
        431  bytes received via SQL*Net from client
          3  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
        153  rows processed



SQL&#62; drop index FBI_REQUESTS_P;

Index dropped.

SQL&#62; create index fbi_requests_p
  2   on requests
  3   (case processed when 0 then mod(subs_id, 7) end,
  4   case processed when 0 then insert_time end);

Index created.

SQL&#62; exec dbms_stats.gather_table_stats(user, 'requests', cascade =&#62; true);

PL/SQL procedure successfully completed.

SQL&#62; select /*+ index(r fbi_requests_p) */ *
  2    from requests r
  3   where case processed when 0 then mod(subs_id, 7) end=:dequeue_process_number
  4    order by case processed when 0 then insert_time end;

153 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 1059845571

----------------------------------------------------------------------------------------------
&#124; Id  &#124; Operation                   &#124; Name           &#124; Rows  &#124; Bytes &#124; Cost (%CPU)&#124; Time     &#124;
----------------------------------------------------------------------------------------------
&#124;   0 &#124; SELECT STATEMENT            &#124;                &#124;   143 &#124;  2431 &#124;    95   (0)&#124; 00:00:02 &#124;
&#124;   1 &#124;  TABLE ACCESS BY INDEX ROWID&#124; REQUESTS       &#124;   143 &#124;  2431 &#124;    95   (0)&#124; 00:00:02 &#124;
&#124;*  2 &#124;   INDEX RANGE SCAN          &#124; FBI_REQUESTS_P &#124;   143 &#124;       &#124;     2   (0)&#124; 00:00:01 &#124;
----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access(CASE "PROCESSED" WHEN 0 THEN MOD("SUBS_ID",7) END
              =TO_NUMBER(:DEQUEUE_PROCESS_NUMBER))


Statistics
----------------------------------------------------------
        171  recursive calls
          0  db block gets
        140  consistent gets
          0  physical reads
          0  redo size
       3278  bytes sent via SQL*Net to client
        431  bytes received via SQL*Net from client
          3  SQL*Net roundtrips to/from client
          4  sorts (memory)
          0  sorts (disk)
        153  rows processed</description>
		<content:encoded><![CDATA[<p>Hi,</p>
<p>Just for curiosity I tested in 11.1.0.6. In 11g it seems that we do not have to add the redundant expression into the order by clause. See below</p>
<p>SQL&gt;  create table requests ( subs_id  number(10), insert_time date, processed number(3));</p>
<p>Table created.</p>
<p>SQL&gt; create index fbi_requests_p<br />
  2  on requests<br />
  3  (case processed when 0 then mod(subs_id, 7) end);</p>
<p>Index created.</p>
<p>SQL&gt; insert /*+ append */ into requests<br />
  2     select trunc(dbms_random.value(0, 10000)),<br />
  3            trunc(sysdate)+dbms_random.value(0, 1),<br />
  4            case when rownum  commit;</p>
<p>Commit complete.</p>
<p>SQL&gt; exec dbms_stats.gather_table_stats(user, &#8216;requests&#8217;, cascade =&gt; true);</p>
<p>PL/SQL procedure successfully completed.</p>
<p>SQL&gt; select /*+ index(r fbi_requests_p) */ *<br />
  from requests r<br />
 where case processed when 0 then mod(subs_id, 7) end=:dequeue_process_number<br />
   order by insert_time<br />
  2    3    4    5<br />
SQL&gt; /</p>
<p>153 rows selected.</p>
<p>Execution Plan<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
Plan hash value: 564389291</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
| Id  | Operation                    | Name           | Rows  | Bytes | Cost (%CPU)| Time     |<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
|   0 | SELECT STATEMENT             |                |   143 |  2145 |     6  (17)| 00:00:01 |<br />
|   1 |  SORT ORDER BY               |                |   143 |  2145 |     6  (17)| 00:00:01 |<br />
|   2 |   TABLE ACCESS BY INDEX ROWID| REQUESTS       |   143 |  2145 |     5   (0)| 00:00:01 |<br />
|*  3 |    INDEX RANGE SCAN          | FBI_REQUESTS_P |   143 |       |     1   (0)| 00:00:01 |<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>Predicate Information (identified by operation id):<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>   3 - access(CASE &#8220;PROCESSED&#8221; WHEN 0 THEN MOD(&#8221;SUBS_ID&#8221;,7) END<br />
              =TO_NUMBER(:DEQUEUE_PROCESS_NUMBER))</p>
<p>Statistics<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
          0  recursive calls<br />
          0  db block gets<br />
          5  consistent gets<br />
          0  physical reads<br />
          0  redo size<br />
       3278  bytes sent via SQL*Net to client<br />
        431  bytes received via SQL*Net from client<br />
          3  SQL*Net roundtrips to/from client<br />
          1  sorts (memory)<br />
          0  sorts (disk)<br />
        153  rows processed</p>
<p>SQL&gt; drop index FBI_REQUESTS_P;</p>
<p>Index dropped.</p>
<p>SQL&gt; create index fbi_requests_p<br />
  2   on requests<br />
  3   (case processed when 0 then mod(subs_id, 7) end,<br />
  4   case processed when 0 then insert_time end);</p>
<p>Index created.</p>
<p>SQL&gt; exec dbms_stats.gather_table_stats(user, &#8216;requests&#8217;, cascade =&gt; true);</p>
<p>PL/SQL procedure successfully completed.</p>
<p>SQL&gt; select /*+ index(r fbi_requests_p) */ *<br />
  2    from requests r<br />
  3   where case processed when 0 then mod(subs_id, 7) end=:dequeue_process_number<br />
  4    order by case processed when 0 then insert_time end;</p>
<p>153 rows selected.</p>
<p>Execution Plan<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
Plan hash value: 1059845571</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
| Id  | Operation                   | Name           | Rows  | Bytes | Cost (%CPU)| Time     |<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
|   0 | SELECT STATEMENT            |                |   143 |  2431 |    95   (0)| 00:00:02 |<br />
|   1 |  TABLE ACCESS BY INDEX ROWID| REQUESTS       |   143 |  2431 |    95   (0)| 00:00:02 |<br />
|*  2 |   INDEX RANGE SCAN          | FBI_REQUESTS_P |   143 |       |     2   (0)| 00:00:01 |<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>Predicate Information (identified by operation id):<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>   2 - access(CASE &#8220;PROCESSED&#8221; WHEN 0 THEN MOD(&#8221;SUBS_ID&#8221;,7) END<br />
              =TO_NUMBER(:DEQUEUE_PROCESS_NUMBER))</p>
<p>Statistics<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
        171  recursive calls<br />
          0  db block gets<br />
        140  consistent gets<br />
          0  physical reads<br />
          0  redo size<br />
       3278  bytes sent via SQL*Net to client<br />
        431  bytes received via SQL*Net from client<br />
          3  SQL*Net roundtrips to/from client<br />
          4  sorts (memory)<br />
          0  sorts (disk)<br />
        153  rows processed</p>
]]></content:encoded>
	</item>
</channel>
</rss>
