<?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"
	>
<channel>
	<title>Comments on: Discarding the Output of a Select Statement</title>
	<atom:link href="http://oraclesponge.wordpress.com/2008/04/01/discarding-the-output-of-a-select-statement/feed/" rel="self" type="application/rss+xml" />
	<link>http://oraclesponge.wordpress.com/2008/04/01/discarding-the-output-of-a-select-statement/</link>
	<description>Oracle Data Warehouse Design and Architecture</description>
	<pubDate>Fri, 04 Jul 2008 18:48:19 +0000</pubDate>
	<generator>http://wordpress.org/?v=MU</generator>
		<item>
		<title>By: Log Buffer #91: a Carnival of the Vanities for DBAs</title>
		<link>http://oraclesponge.wordpress.com/2008/04/01/discarding-the-output-of-a-select-statement/#comment-50908</link>
		<dc:creator>Log Buffer #91: a Carnival of the Vanities for DBAs</dc:creator>
		<pubDate>Fri, 04 Apr 2008 16:51:21 +0000</pubDate>
		<guid isPermaLink="false">http://oraclesponge.wordpress.com/?p=362#comment-50908</guid>
		<description>[...] Aldridge, the Oracle Sponge, looks into discarding the output of a select statement: &#8220;.&#160;.&#160;.&#160;you want to run a select for a big bunch of rows, maybe for measuring [...]</description>
		<content:encoded><![CDATA[<p>[...] Aldridge, the Oracle Sponge, looks into discarding the output of a select statement: &#8220;.&nbsp;.&nbsp;.&nbsp;you want to run a select for a big bunch of rows, maybe for measuring [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Alex Gorbachev</title>
		<link>http://oraclesponge.wordpress.com/2008/04/01/discarding-the-output-of-a-select-statement/#comment-50900</link>
		<dc:creator>Alex Gorbachev</dc:creator>
		<pubDate>Thu, 03 Apr 2008 23:30:12 +0000</pubDate>
		<guid isPermaLink="false">http://oraclesponge.wordpress.com/?p=362#comment-50900</guid>
		<description>Btw, Jonathan Lewis has done few interesting posts on similar topic (but not exactly with the same purpose in mind) and there is another hint he was talking about - NO_MERGE.</description>
		<content:encoded><![CDATA[<p>Btw, Jonathan Lewis has done few interesting posts on similar topic (but not exactly with the same purpose in mind) and there is another hint he was talking about - NO_MERGE.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Brian Tkatch</title>
		<link>http://oraclesponge.wordpress.com/2008/04/01/discarding-the-output-of-a-select-statement/#comment-50892</link>
		<dc:creator>Brian Tkatch</dc:creator>
		<pubDate>Thu, 03 Apr 2008 14:49:19 +0000</pubDate>
		<guid isPermaLink="false">http://oraclesponge.wordpress.com/?p=362#comment-50892</guid>
		<description>Very interesting thread and results. 

Thanx David.</description>
		<content:encoded><![CDATA[<p>Very interesting thread and results. </p>
<p>Thanx David.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: David Aldridge</title>
		<link>http://oraclesponge.wordpress.com/2008/04/01/discarding-the-output-of-a-select-statement/#comment-50891</link>
		<dc:creator>David Aldridge</dc:creator>
		<pubDate>Wed, 02 Apr 2008 23:12:07 +0000</pubDate>
		<guid isPermaLink="false">http://oraclesponge.wordpress.com/?p=362#comment-50891</guid>
		<description>Hmmm, is that hint valid in the context of an in-line view? It produces a different execution plan to the subquery factoring alternative and is the same as if it weren't there ...

explain plan for select count(*) from (select /*+ materialize */ * from s_order);
select * from table(dbms_xplan.display);

explain plan for select count(*) from (select * from s_order);
select * from table(dbms_xplan.display);

explain plan for 
with rowset as(select /*+ materialize */ * from s_order)
 select count(*) from rowset;
 
select * from table(dbms_xplan.display);

These give me:

----------------------------------------------------------------------         
&#124; Id  &#124; Operation          &#124; Name    &#124; Rows  &#124; Cost (%CPU)&#124; Time     &#124;         
----------------------------------------------------------------------         
&#124;   0 &#124; SELECT STATEMENT   &#124;         &#124;     1 &#124;   443K  (1)&#124; 02:13:01 &#124;         
&#124;   1 &#124;  SORT AGGREGATE    &#124;         &#124;     1 &#124;            &#124;          &#124;         
&#124;   2 &#124;   TABLE ACCESS FULL&#124; S_ORDER &#124;    11M&#124;   443K  (1)&#124; 02:13:01 &#124;         
----------------------------------------------------------------------         

and 

----------------------------------------------------------------------         
&#124; Id  &#124; Operation          &#124; Name    &#124; Rows  &#124; Cost (%CPU)&#124; Time     &#124;         
----------------------------------------------------------------------         
&#124;   0 &#124; SELECT STATEMENT   &#124;         &#124;     1 &#124;   443K  (1)&#124; 02:13:01 &#124;         
&#124;   1 &#124;  SORT AGGREGATE    &#124;         &#124;     1 &#124;            &#124;          &#124;         
&#124;   2 &#124;   TABLE ACCESS FULL&#124; S_ORDER &#124;    11M&#124;   443K  (1)&#124; 02:13:01 &#124;         
----------------------------------------------------------------------         


and 

----------------------------------------------------------------------------------------------------------          
&#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;       &#124;   532K  (2)&#124; 02:39:50 &#124;          
&#124;   1 &#124;  TEMP TABLE TRANSFORMATION &#124;                             &#124;       &#124;       &#124;            &#124;          &#124;          
&#124;   2 &#124;   LOAD AS SELECT           &#124;                             &#124;       &#124;       &#124;            &#124;          &#124;          
&#124;   3 &#124;    TABLE ACCESS FULL       &#124; S_ORDER                     &#124;    11M&#124;  5052M&#124;   446K  (1)&#124; 02:13:56 &#124;          
&#124;   4 &#124;   SORT AGGREGATE           &#124;                             &#124;     1 &#124;       &#124;            &#124;          &#124;          
&#124;   5 &#124;    VIEW                    &#124;                             &#124;    11M&#124;       &#124; 86334   (4)&#124; 00:25:55 &#124;          
&#124;   6 &#124;     TABLE ACCESS FULL      &#124; SYS_TEMP_0FD9D6600_36AEF106 &#124;    11M&#124;  5052M&#124; 86334   (4)&#124; 00:25:55 &#124;          
----------------------------------------------------------------------------------------------------------          

It's interesting that the cost of the full table scan varies there between 443K and 446K. I wonder why?</description>
		<content:encoded><![CDATA[<p>Hmmm, is that hint valid in the context of an in-line view? It produces a different execution plan to the subquery factoring alternative and is the same as if it weren&#8217;t there &#8230;</p>
<p>explain plan for select count(*) from (select /*+ materialize */ * from s_order);<br />
select * from table(dbms_xplan.display);</p>
<p>explain plan for select count(*) from (select * from s_order);<br />
select * from table(dbms_xplan.display);</p>
<p>explain plan for<br />
with rowset as(select /*+ materialize */ * from s_order)<br />
 select count(*) from rowset;</p>
<p>select * from table(dbms_xplan.display);</p>
<p>These give me:</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;-<br />
| Id  | Operation          | Name    | Rows  | 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;-<br />
|   0 | SELECT STATEMENT   |         |     1 |   443K  (1)| 02:13:01 |<br />
|   1 |  SORT AGGREGATE    |         |     1 |            |          |<br />
|   2 |   TABLE ACCESS FULL| S_ORDER |    11M|   443K  (1)| 02:13: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;-         </p>
<p>and </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;-<br />
| Id  | Operation          | Name    | Rows  | 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;-<br />
|   0 | SELECT STATEMENT   |         |     1 |   443K  (1)| 02:13:01 |<br />
|   1 |  SORT AGGREGATE    |         |     1 |            |          |<br />
|   2 |   TABLE ACCESS FULL| S_ORDER |    11M|   443K  (1)| 02:13: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;-         </p>
<p>and </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;&#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;&#8212;&#8212;&#8212;&#8212;-<br />
|   0 | SELECT STATEMENT           |                             |     1 |       |   532K  (2)| 02:39:50 |<br />
|   1 |  TEMP TABLE TRANSFORMATION |                             |       |       |            |          |<br />
|   2 |   LOAD AS SELECT           |                             |       |       |            |          |<br />
|   3 |    TABLE ACCESS FULL       | S_ORDER                     |    11M|  5052M|   446K  (1)| 02:13:56 |<br />
|   4 |   SORT AGGREGATE           |                             |     1 |       |            |          |<br />
|   5 |    VIEW                    |                             |    11M|       | 86334   (4)| 00:25:55 |<br />
|   6 |     TABLE ACCESS FULL      | SYS_TEMP_0FD9D6600_36AEF106 |    11M|  5052M| 86334   (4)| 00:25:55 |<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;&#8212;&#8212;&#8212;&#8212;-          </p>
<p>It&#8217;s interesting that the cost of the full table scan varies there between 443K and 446K. I wonder why?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Alex Gorbachev</title>
		<link>http://oraclesponge.wordpress.com/2008/04/01/discarding-the-output-of-a-select-statement/#comment-50890</link>
		<dc:creator>Alex Gorbachev</dc:creator>
		<pubDate>Wed, 02 Apr 2008 22:38:00 +0000</pubDate>
		<guid isPermaLink="false">http://oraclesponge.wordpress.com/?p=362#comment-50890</guid>
		<description>What about:
&lt;code&gt;select count(*) from (select /*+ materialize */ * from s_order where ...);&lt;/code&gt;</description>
		<content:encoded><![CDATA[<p>What about:<br />
<code>select count(*) from (select /*+ materialize */ * from s_order where ...);</code></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: David Aldridge</title>
		<link>http://oraclesponge.wordpress.com/2008/04/01/discarding-the-output-of-a-select-statement/#comment-50889</link>
		<dc:creator>David Aldridge</dc:creator>
		<pubDate>Wed, 02 Apr 2008 19:41:42 +0000</pubDate>
		<guid isPermaLink="false">http://oraclesponge.wordpress.com/?p=362#comment-50889</guid>
		<description>I think the first_rows issue is to be expected. Oracle probably overrides first_rows with all_rows when performing an insert. Something to bear in mind.

The change I usually see when people use a count(*) is that Oracle naturaly gets more index-happy. The count(*) can often be satisfied from an index, whereas the projecting the contents of columns is more likely to require table access.</description>
		<content:encoded><![CDATA[<p>I think the first_rows issue is to be expected. Oracle probably overrides first_rows with all_rows when performing an insert. Something to bear in mind.</p>
<p>The change I usually see when people use a count(*) is that Oracle naturaly gets more index-happy. The count(*) can often be satisfied from an index, whereas the projecting the contents of columns is more likely to require table access.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Gabe</title>
		<link>http://oraclesponge.wordpress.com/2008/04/01/discarding-the-output-of-a-select-statement/#comment-50888</link>
		<dc:creator>Gabe</dc:creator>
		<pubDate>Wed, 02 Apr 2008 17:19:19 +0000</pubDate>
		<guid isPermaLink="false">http://oraclesponge.wordpress.com/?p=362#comment-50888</guid>
		<description>I think there is the same side effect with the INSERT ALL method as with the COUNT(*) one.

I tested in a 10.1 instance.
First run: execute the following as is
Second run: uncomment the optimizer_mode statement.

My observations:
With the default optimizer_mode setting, the INSERT ALL did what my target statement naturally wanted to do; the COUNT(*) did not.
With the optimizer_mode set to first_rows, the INSERT ALL did not what the target statement naturally wanted to do; the COUNT(*) did.

&lt;code&gt;
create table t as select object_id a, object_name b, object_type c from all_objects;
create index c on t (c);
insert into t select * from t order by dbms_random.random;
insert into t select * from t order by dbms_random.random;
insert into t select * from t order by dbms_random.random;
exec dbms_stats.gather_table_stats(user,'T',cascade=&#62;true)

-- just to show the clustering factor stays roughly the same
select blevel, leaf_blocks, distinct_keys
      ,avg_leaf_blocks_per_key,avg_data_blocks_per_key
      ,clustering_factor,num_rows
from user_indexes where index_name='C';

-- uncomment this on the second run
--alter session set optimizer_mode=first_rows;

-- this is the target statement
explain plan for select * from t where c='SYNONYM';
select * from table(dbms_xplan.display());

explain plan for select /*+ first_rows */ * from t where c='SYNONYM';
select * from table(dbms_xplan.display());

explain plan for insert all when 1=0 then into t select * from t where c='SYNONYM';
select * from table(dbms_xplan.display());

explain plan for select count(*) from ( select * from t where c='SYNONYM' );
select * from table(dbms_xplan.display());

drop table t purge;
&lt;/code&gt;</description>
		<content:encoded><![CDATA[<p>I think there is the same side effect with the INSERT ALL method as with the COUNT(*) one.</p>
<p>I tested in a 10.1 instance.<br />
First run: execute the following as is<br />
Second run: uncomment the optimizer_mode statement.</p>
<p>My observations:<br />
With the default optimizer_mode setting, the INSERT ALL did what my target statement naturally wanted to do; the COUNT(*) did not.<br />
With the optimizer_mode set to first_rows, the INSERT ALL did not what the target statement naturally wanted to do; the COUNT(*) did.</p>
<p><code><br />
create table t as select object_id a, object_name b, object_type c from all_objects;<br />
create index c on t (c);<br />
insert into t select * from t order by dbms_random.random;<br />
insert into t select * from t order by dbms_random.random;<br />
insert into t select * from t order by dbms_random.random;<br />
exec dbms_stats.gather_table_stats(user,'T',cascade=&gt;true)</p>
<p>-- just to show the clustering factor stays roughly the same<br />
select blevel, leaf_blocks, distinct_keys<br />
      ,avg_leaf_blocks_per_key,avg_data_blocks_per_key<br />
      ,clustering_factor,num_rows<br />
from user_indexes where index_name='C';</p>
<p>-- uncomment this on the second run<br />
--alter session set optimizer_mode=first_rows;</p>
<p>-- this is the target statement<br />
explain plan for select * from t where c='SYNONYM';<br />
select * from table(dbms_xplan.display());</p>
<p>explain plan for select /*+ first_rows */ * from t where c='SYNONYM';<br />
select * from table(dbms_xplan.display());</p>
<p>explain plan for insert all when 1=0 then into t select * from t where c='SYNONYM';<br />
select * from table(dbms_xplan.display());</p>
<p>explain plan for select count(*) from ( select * from t where c='SYNONYM' );<br />
select * from table(dbms_xplan.display());</p>
<p>drop table t purge;<br />
</code></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: David Aldridge</title>
		<link>http://oraclesponge.wordpress.com/2008/04/01/discarding-the-output-of-a-select-statement/#comment-50887</link>
		<dc:creator>David Aldridge</dc:creator>
		<pubDate>Wed, 02 Apr 2008 15:15:47 +0000</pubDate>
		<guid isPermaLink="false">http://oraclesponge.wordpress.com/?p=362#comment-50887</guid>
		<description>I think that in Richard's case that choice was dictated by needing to run several thousands of select statements, but the principle stil works the same I suppose. You'd have to do some bulk collect thing ... that might be too much like hard work for me.</description>
		<content:encoded><![CDATA[<p>I think that in Richard&#8217;s case that choice was dictated by needing to run several thousands of select statements, but the principle stil works the same I suppose. You&#8217;d have to do some bulk collect thing &#8230; that might be too much like hard work for me.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Brian Tkatch</title>
		<link>http://oraclesponge.wordpress.com/2008/04/01/discarding-the-output-of-a-select-statement/#comment-50886</link>
		<dc:creator>Brian Tkatch</dc:creator>
		<pubDate>Wed, 02 Apr 2008 15:07:54 +0000</pubDate>
		<guid isPermaLink="false">http://oraclesponge.wordpress.com/?p=362#comment-50886</guid>
		<description>Cute.

Personally, i test by shrinking the SQL*Plus window. Yes, yes, i know.

If i really cared, wouldn't a PL/SQL routine be best? Just put the returns into variables and throw it away. (That's what Richard did in his example here http://richardfoote.wordpress.com/2008/03/31/larger-block-index-tablespace-and-small-index-scans-performance-improvement-let-down/)</description>
		<content:encoded><![CDATA[<p>Cute.</p>
<p>Personally, i test by shrinking the SQL*Plus window. Yes, yes, i know.</p>
<p>If i really cared, wouldn&#8217;t a PL/SQL routine be best? Just put the returns into variables and throw it away. (That&#8217;s what Richard did in his example here <a href="http://richardfoote.wordpress.com/2008/03/31/larger-block-index-tablespace-and-small-index-scans-performance-improvement-let-down/" rel="nofollow">http://richardfoote.wordpress.com/2008/03/31/larger-block-index-tablespace-and-small-index-scans-performance-improvement-let-down/</a>)</p>
]]></content:encoded>
	</item>
</channel>
</rss>
