<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	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:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Striving for Optimal PerformanceStriving for Optimal Performance &#187; TOP</title>
	<atom:link href="http://www.antognini.ch/category/top/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.antognini.ch</link>
	<description></description>
	<lastBuildDate>Fri, 18 May 2012 11:35:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Index Scan with Filter Predicate Based on a Subquery</title>
		<link>http://www.antognini.ch/2012/02/index-scan-with-filter-predicate-based-on-a-subquery/</link>
		<comments>http://www.antognini.ch/2012/02/index-scan-with-filter-predicate-based-on-a-subquery/#comments</comments>
		<pubDate>Mon, 06 Feb 2012 21:36:58 +0000</pubDate>
		<dc:creator>Christian Antognini</dc:creator>
				<category><![CDATA[10gR2]]></category>
		<category><![CDATA[11gR1]]></category>
		<category><![CDATA[11gR2]]></category>
		<category><![CDATA[Bug]]></category>
		<category><![CDATA[Query Optimizer]]></category>
		<category><![CDATA[TOP]]></category>

		<guid isPermaLink="false">http://antognini.ch/?p=1705</guid>
		<description><![CDATA[Most execution plans can be interpreted by following few basic rules (in TOP, Chapter 6, I provide such a list of rules). Nevertheless, there are some special cases. One of them is when an index scan, in addition to the access predicate, has a filter predicate applying a subquery. The following execution plan, taken from [...]]]></description>
			<content:encoded><![CDATA[<p>Most execution plans can be interpreted by following few basic rules (in TOP, Chapter 6, I provide such a list of rules). Nevertheless, there are some special cases. One of them is when an index scan, in addition to the access predicate, has a filter predicate applying a subquery.</p>
<p>The following execution plan, taken from Enterprise Manager 11.2, is an example (click on the image to increase its size):<br />
<a href="/images/ep20120206.jpg" rel="lightbox" title="Index Scan with Filter Predicate Based on a Subquery"><img id="exeplan" src="/images/ep20120206.jpg" alt="Execution Plan" width="550px" /></a><br />
Notes:</p>
<ul>
<li>According to the order column the first operation being executed is the scan of the <code>I2</code> index. Unfortunately this is wrong. In fact the first operation being executed is the scan of the <code>I1</code> index. This is a bug in Enterprise Manager. I wanted to show you this example to demonstrate that not only for us it might be difficult to correctly interpret an execution plan <img src='http://www.antognini.ch/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </li>
<li>The filter predicate <code>IS NOT NULL</code> is also wrong. This is not a bug, however. It is a limitation in the current implementation. The problem is that in some cases the <code>V$SQL_PLAN</code> and <code>V$SQL_PLAN_STATISTICS_ALL</code> views are not able to show all the necessary details.</li>
</ul>
<p>Without seeing the query on which this execution plan is based, it is not obvious at all to know what’s going on. So, here is the query:</p>
<pre>SELECT *
FROM t1
WHERE n1 = 8
AND n2 IN (SELECT t2.n1 FROM t2, t3 WHERE t2.id = t3.id AND t3.n1 = <img src='http://www.antognini.ch/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /> </pre>
<p>Based on the query it is essential to point out that the access predicate <code>"T2"."N1"=:B1</code> cannot be evaluated and, therefore, the scan of the <code>I2</code> index cannot be carried out, without having a value passed through the B1 bind variable. In other words, without knowing the value of <code>T1.N2</code>.</p>
<p>To describe how this execution plan is carried out, let’s have a look to the information provided by the <code>DBMS_XPLAN.DISPLAY</code> function (which does not expose the limitation related to the filter predicate).</p>
<pre>-----------------------------------------------
| Id  | Operation                      | Name |
-----------------------------------------------
|   0 | SELECT STATEMENT               |      |
|   1 |  TABLE ACCESS BY INDEX ROWID   | T1   |
|*  2 |   INDEX RANGE SCAN             | I1   |
|   3 |    NESTED LOOPS                |      |
|   4 |     TABLE ACCESS BY INDEX ROWID| T2   |
|*  5 |      INDEX RANGE SCAN          | I2   |
|*  6 |     TABLE ACCESS BY INDEX ROWID| T3   |
|*  7 |      INDEX RANGE SCAN          | I3   |
-----------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("N1"=8)
    filter( EXISTS (SELECT /*+ LEADING ("T2" "T3") USE_NL ("T3") INDEX
           ("T3" "I3") INDEX_RS_ASC ("T2" "I2") */ 0 FROM "T3" "T3","T2" "T2" WHERE
           "T2"."N1"=:B1 AND "T3"."N1"=8 AND "T2"."ID"="T3"."ID"))
5 - access("T2"."N1"=:B1)
6 - filter("T2"."ID"="T3"."ID")
7 - access("T3"."N1"=8)</pre>
<p>The operations are carried out as follows:</p>
<ol>
<li>Operation 2 applies the access predicate <code>"N1"=8</code> by scanning the <code>I1</code> index.</li>
<li>For each key returned by the previous scan, the subquery is executed once. Note that the subquery carries out a nested loop. While the outer loop accesses the <code>T2</code> table, the inner loop accesses the <code>T3</code> table. </li>
<li>The first operation of the outer loop is operation 5. It applies the access predicate <code>"T2"."N1"=:B1</code> by scanning the <code>I2</code> index. Based on the rowid returned by the index access the <code>T2</code> table is accessed (operation 4).</li>
<li>For each row returned by the outer loop, the inner loop is executed once. The first operation of the inner loop is operation 7. It applies the access predicate <code>"T3"."N1"=8</code> by scanning the <code>I3</code> index. Based on the rowid returned by the index access the <code>T3</code> table is accessed (operation 6) and the filter predicate <code>"T2"."ID"="T3"."ID"</code> (the join condition) is applied. By the way, it is interesting to notice that, contrary to the join condition is <em>not</em> applied as an access predicate, as it usually happens.</li>
<li>If the subquery returns a row, the rowid returned by operation 2 can be used to access the <code>T1</code> table (operation 1). The row extracted from this operation is sent to the caller.</li>
</ol>
<p>All in all, this is a very special execution plan&#8230;</p>
<p>In summary, be careful when you see an index scan with a filter predicate applying a subquery. The execution plan might not be carried out as you expect at first sight. It is also essential to point out that in such a case the predicate information is essential to fully understand what’s going on.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.antognini.ch/2012/02/index-scan-with-filter-predicate-based-on-a-subquery/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Ad: The Oracle Query Optimizer 2-Day Seminar</title>
		<link>http://www.antognini.ch/2011/12/ad-the-oracle-query-optimizer-two-day-seminar/</link>
		<comments>http://www.antognini.ch/2011/12/ad-the-oracle-query-optimizer-two-day-seminar/#comments</comments>
		<pubDate>Sat, 17 Dec 2011 23:42:45 +0000</pubDate>
		<dc:creator>Christian Antognini</dc:creator>
				<category><![CDATA[Query Optimizer]]></category>
		<category><![CDATA[Speaking]]></category>
		<category><![CDATA[TOP]]></category>

		<guid isPermaLink="false">http://antognini.ch/?p=1689</guid>
		<description><![CDATA[The 31st of January and 1st of February 2012 I will present a 2-day seminar about the Oracle query optimizer in Ballerup (DK). The event is organized by Miracle A/S. The content, which is based on the chapters 2, 4, 5, 6, 9 and 10 of my book, is the following: Chapter 1 describes the [...]]]></description>
			<content:encoded><![CDATA[<p>The 31st of January and 1st of February 2012 I will present a 2-day seminar about the Oracle query optimizer in Ballerup (DK). The event is organized by <a href="http://www.miracleas.dk/">Miracle A/S</a>. The content, which is based on the chapters 2, 4, 5, 6, 9 and 10 of <a href="/top">my book</a>, is the following:</p>
<ul>
<li>Chapter 1 describes the life cycle of SQL statements and when the database engine can share cursors.</li>
<li>Chapter 2 describes the aim and architecture of the query optimizer.</li>
<li>Chapter 3 and 4 discuss the statistics used by the query optimizer to carry out its work.</li>
<li>Chapter 5 describes the initialization parameters influencing the behavior of the query optimizer and how to set them.</li>
<li>Chapter 6 outlines different methods of obtaining execution plans, as well as how to read them and recognize inefficient ones.</li>
<li>Chapter 7 describes how to take advantage of available access structures in order to access data stored in a single table efficiently.</li>
<li>Chapter 8 goes beyond accessing a single table, by describing how to join data from several tables together.</li>
</ul>
<p>The <a href="http://antognini.ch/downloads/Miracle_TheOracleQueryOptimizer_20110131.pdf">flyer</a> and this page provide detailed information about the seminar.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.antognini.ch/2011/12/ad-the-oracle-query-optimizer-two-day-seminar/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>optimizer_secure_view_merging and VPD</title>
		<link>http://www.antognini.ch/2011/09/optimizer_secure_view_merging-and-vpd/</link>
		<comments>http://www.antognini.ch/2011/09/optimizer_secure_view_merging-and-vpd/#comments</comments>
		<pubDate>Sun, 11 Sep 2011 09:21:49 +0000</pubDate>
		<dc:creator>Christian Antognini</dc:creator>
				<category><![CDATA[10gR2]]></category>
		<category><![CDATA[11gR1]]></category>
		<category><![CDATA[11gR2]]></category>
		<category><![CDATA[Query Optimizer]]></category>
		<category><![CDATA[TOP]]></category>

		<guid isPermaLink="false">http://antognini.ch/?p=1552</guid>
		<description><![CDATA[At page 189 of TOP I wrote the following piece of text: In summary, with the initialization parameter optimizer_secure_view_merging set to TRUE, the query optimizer checks whether view merging could lead to security issues. If this is the case, no view merging will be performed, and performance could be suboptimal as a result. For this [...]]]></description>
			<content:encoded><![CDATA[<p>At page 189 of <a href="/top">TOP</a> I wrote the following piece of text:</p>
<blockquote><p>In summary, with the initialization parameter optimizer_secure_view_merging set to TRUE, the query optimizer checks whether view merging could lead to security issues. If this is the case, no view merging will be performed, and performance could be suboptimal as a result. For this reason, if you are not using views for security purposes, it is better to set this initialization parameter to FALSE.</p></blockquote>
<p>What I didn’t consider when I wrote it, it is the implication of predicate move-around related to Virtual Private Database (VPD). In fact, as described in the <a href="http://download.oracle.com/docs/cd/E11882_01/server.112/e17110/initparams168.htm#I1010262">documentation</a>, that parameter controls <em>view merging</em> as well as <em>predicate move-around</em>.</p>
<p>To point out what the impact is, let’s have a look to an example based on the description provided in <a href="/top">TOP</a>:</p>
<ul>
<li>Say you have a very simple table with one primary key and two more columns.</li>
</ul>
<pre>CREATE TABLE t (
  id NUMBER(10) PRIMARY KEY,
  class NUMBER(10),
  pad VARCHAR2(10)
);</pre>
<ul>
<li>For security reasons, you define the following policy. Notice the filter that is applied with the function to partially show the content of the table. How this function is implemented and what it does exactly is not important.</li>
</ul>
<pre>CREATE OR REPLACE FUNCTION s (schema IN VARCHAR2, tab IN VARCHAR2) RETURN VARCHAR2 AS
BEGIN
  RETURN 'f(class) = 1';
END;
/

BEGIN
  dbms_rls.add_policy(object_schema   => 'U1',
                      object_name     => 'T',
                      policy_name     => 'T_SEC',
                      function_schema => 'U1',
                      policy_function => 'S');
END;
/</pre>
<ul>
<li>Now let’s say that a user who has access to the table creates the following PL/SQL function. As you can see, it will just display the value of the input parameters through a call to the package dbms_output.</li>
</ul>
<pre>CREATE OR REPLACE FUNCTION spy (id IN NUMBER, pad IN VARCHAR2) RETURN NUMBER AS
BEGIN
  dbms_output.put_line('id=' || id || ' pad=' || pad);
  RETURN 1;
END;
/</pre>
<ul>
<li>With the initialization parameter optimizer_secure_view_merging set to FALSE, you can run two test queries. Both return only the values that the user is allowed to see. In the second one, however, you are able to see data that you should not be able to access.</li>
</ul>
<pre>SQL> SELECT id, pad
  2  FROM t
  3  WHERE id BETWEEN 1 AND 5;

        ID PAD
---------- ----------
         1 DrMLTDXxxq
         4 AszBGEUGEL

SQL> SELECT id, pad
  2  FROM t
  3  WHERE id BETWEEN 1 AND 5
  4  AND spy(id, pad) = 1;

        ID PAD
---------- ----------
         1 DrMLTDXxxq
         4 AszBGEUGEL
id=1 pad=DrMLTDXxxq
id=2 pad=XOZnqYRJwI
id=3 pad=nlGfGBTxNk
id=4 pad=AszBGEUGEL
id=5 pad=qTSRnFjRGb</pre>
<ul>
<li>With the initialization parameter optimizer_secure_view_merging set to TRUE, the second query returns the following output. As you can see, the function and the query display the same data.</li>
</ul>
<pre>SQL> SELECT id, pad
  2  FROM t
  3  WHERE id BETWEEN 1 AND 5
  4  AND spy(id, pad) = 1;

        ID PAD
---------- ----------
         1 DrMLTDXxxq
         4 AszBGEUGEL
id=1 pad=DrMLTDXxxq
id=4 pad=AszBGEUGEL</pre>
<p>The execution plans that are used in the two situations are the following. As you can see only the second one guarantee that the policy defined via VPD is applied before the predicate based on the SPY function. Interestingly enough the other predicate based on the ID column is applied before the one of the policy. Hence, the query optimizer can choose an access path that takes advantage of the primary key.</p>
<ul>
<li>optimizer_secure_view_merging = FALSE</li>
</ul>
<pre>---------------------------------------------------
| Id  | Operation                   | Name        |
---------------------------------------------------
|   0 | SELECT STATEMENT            |             |
|*  1 |  TABLE ACCESS BY INDEX ROWID| T           |
|*  2 |   INDEX RANGE SCAN          | SYS_C009970 |
---------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(("SPY"("ID","PAD")=1 AND "F"("CLASS")=1))
   2 - access("ID">=1 AND "ID"<=5)</pre>
<ul>
<li>optimizer_secure_view_merging = TRUE</li>
</ul>
<pre>----------------------------------------------------
| Id  | Operation                    | Name        |
----------------------------------------------------
|   0 | SELECT STATEMENT             |             |
|*  1 |  VIEW                        | T           |
|*  2 |   TABLE ACCESS BY INDEX ROWID| T           |
|*  3 |    INDEX RANGE SCAN          | SYS_C009971 |
----------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("SPY"("ID","PAD")=1)
   2 - filter("F"("CLASS")=1)
   3 - access("ID">=1 AND "ID"<=5)</pre>
<p>Based on these observations, the summary that is provided by <a href="/top">TOP</a> at page 189 should be amended as follows:</p>
<blockquote><p>In summary, with the initialization parameter optimizer_secure_view_merging set to TRUE, the query optimizer checks whether view merging or predicate move-around could lead to security issues. If this is the case, they will not be performed, and performance could be suboptimal as a result. For this reason, if you are not using views or VPD for security purposes, it is better to set this initialization parameter to FALSE.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.antognini.ch/2011/09/optimizer_secure_view_merging-and-vpd/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Ad: DOAG Berliner Expertenseminare (Last Call)</title>
		<link>http://www.antognini.ch/2011/05/ad-doag-berliner-expertenseminare-last-call/</link>
		<comments>http://www.antognini.ch/2011/05/ad-doag-berliner-expertenseminare-last-call/#comments</comments>
		<pubDate>Mon, 23 May 2011 13:51:21 +0000</pubDate>
		<dc:creator>Christian Antognini</dc:creator>
				<category><![CDATA[Speaking]]></category>
		<category><![CDATA[TOP]]></category>

		<guid isPermaLink="false">http://antognini.ch/?p=1520</guid>
		<description><![CDATA[I was just informed that there are still some free seats for the 2-day seminar I will present in Berlin in two weeks (June 7-8). Hence, do not wait too long if you want to join us&#8230; The content is based on the chapters 4, 5, 6 and 7 of my book, i.e. part 3: [...]]]></description>
			<content:encoded><![CDATA[<p>I was just informed that there are still some free seats for the 2-day seminar I will present in Berlin in two weeks (June 7-8). Hence, do not wait too long if you want to join us&#8230;</p>
<p>The content is based on the chapters 4, 5, 6 and 7 of my <a href="/top">book</a>, i.e. part 3: Query Optimizer. The essential difference is that the content was updated to cover version 11.2 as well.</p>
<p>The event is organized by <a href="http://www.doag.org">DOAG</a>. You can read the full description of the seminar (incl. agenda) <a href="http://mydoag.doag.org/termine/termine.php?tid=417402">here</a>. Just be careful that the spoken language will be German (slides will be in English, though).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.antognini.ch/2011/05/ad-doag-berliner-expertenseminare-last-call/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>IS NULL Conditions and B-tree Indexes</title>
		<link>http://www.antognini.ch/2011/02/is-null-conditions-and-b-tree-indexes/</link>
		<comments>http://www.antognini.ch/2011/02/is-null-conditions-and-b-tree-indexes/#comments</comments>
		<pubDate>Thu, 17 Feb 2011 10:01:56 +0000</pubDate>
		<dc:creator>Christian Antognini</dc:creator>
				<category><![CDATA[10gR1]]></category>
		<category><![CDATA[10gR2]]></category>
		<category><![CDATA[11gR1]]></category>
		<category><![CDATA[11gR2]]></category>
		<category><![CDATA[9iR2]]></category>
		<category><![CDATA[Indexes]]></category>
		<category><![CDATA[Query Optimizer]]></category>
		<category><![CDATA[TOP]]></category>

		<guid isPermaLink="false">http://antognini.ch/?p=1479</guid>
		<description><![CDATA[At page 383 of my book I wrote the following sentence (BTW, the same information is also provided by Table 9-3 at page 381): With B-tree indexes, IS NULL conditions can be applied only through composite B-tree indexes when several SQL conditions are applied and at least one of them is not based on IS [...]]]></description>
			<content:encoded><![CDATA[<p>At page 383 of <a href="/top">my book</a> I wrote the following sentence (BTW, the same information is also provided by Table 9-3 at page 381):</p>
<blockquote><p>With B-tree indexes, IS NULL conditions can be applied only through composite B-tree indexes when several SQL conditions are applied and at least one of them is not based on IS NULL or an inequality.</p></blockquote>
<p>The text continues by showing the following examples (notice that in both cases the IS NULL predicate is applied through an access predicate):</p>
<pre>SELECT /*+ index(t) */ * FROM t WHERE n1 = 6 AND n2 IS NULL

Plan hash value: 780655320

----------------------------------------------
| Id  | Operation                   | Name   |
----------------------------------------------
|   0 | SELECT STATEMENT            |        |
|   1 |  TABLE ACCESS BY INDEX ROWID| T      |
|*  2 |   INDEX RANGE SCAN          | I_N123 |
----------------------------------------------

   2 - access("N1"=6 AND "N2" IS NULL)

SELECT /*+ index(t) */ * FROM t WHERE n1 IS NULL AND n2 = 8

Plan hash value: 780655320

----------------------------------------------
| Id  | Operation                   | Name   |
----------------------------------------------
|   0 | SELECT STATEMENT            |        |
|   1 |  TABLE ACCESS BY INDEX ROWID| T      |
|*  2 |   INDEX RANGE SCAN          | I_N123 |
----------------------------------------------

   2 - access("N1" IS NULL AND "N2"=8)
       filter("N2"=8)</pre>
<p>When I wrote that sentence I didn&#8217;t think about one case that, according to it, specifically the part &#8220;is not based on IS NULL or an inequality&#8221;, is not covered. In fact, as the following examples show, it is also possible to apply an IS NULL predicate when the other one is an IS NOT NULL. It is especially interesting to notice that the access predicate doesn&#8217;t reference at all the NOT NULL column!</p>
<pre>SELECT /*+ index(t) */ * FROM t WHERE n1 IS NULL AND n2 IS NOT NULL

Plan hash value: 780655320

----------------------------------------------
| Id  | Operation                   | Name   |
----------------------------------------------
|   0 | SELECT STATEMENT            |        |
|   1 |  TABLE ACCESS BY INDEX ROWID| T      |
|*  2 |   INDEX RANGE SCAN          | I_N123 |
----------------------------------------------

   2 - access("N1" IS NULL)
       filter("N2" IS NOT NULL)

SELECT /*+ index(t) */ * FROM t WHERE n1 IS NOT NULL AND n2 IS NULL

Plan hash value: 3029444779

----------------------------------------------
| Id  | Operation                   | Name   |
----------------------------------------------
|   0 | SELECT STATEMENT            |        |
|   1 |  TABLE ACCESS BY INDEX ROWID| T      |
|*  2 |   INDEX SKIP SCAN           | I_N123 |
----------------------------------------------

   2 - access("N2" IS NULL)
       filter(("N2" IS NULL AND "N1" IS NOT NULL))</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.antognini.ch/2011/02/is-null-conditions-and-b-tree-indexes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SIOUG Conference in Portoroz</title>
		<link>http://www.antognini.ch/2010/08/sioug-conference-in-portoroz/</link>
		<comments>http://www.antognini.ch/2010/08/sioug-conference-in-portoroz/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 12:21:10 +0000</pubDate>
		<dc:creator>Christian Antognini</dc:creator>
				<category><![CDATA[Speaking]]></category>
		<category><![CDATA[TOP]]></category>

		<guid isPermaLink="false">http://antognini.ch/?p=1247</guid>
		<description><![CDATA[This is a short note to point out that I just added to the Public Appearances page the next conference organized by the Slovenian Oracle User Group (SIOUG) in Portoroz. It will take place on September 27-29. My talk, entitled &#8220;Join Techniques&#8221;, is based on chapter 10 of my book. It will be a shorter [...]]]></description>
			<content:encoded><![CDATA[<p>This is a short note to point out that I just added to the <a href="/public-appearances/">Public Appearances</a> page the next conference organized by the <a href="http://www.sioug.si/">Slovenian Oracle User Group (SIOUG)</a> in Portoroz. It will take place on September 27-29. My talk, entitled &#8220;Join Techniques&#8221;, is based on chapter 10 of <a href="/top">my book</a>. It will be a shorter version of then one I will give at Oracle OpenWorld the week before.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.antognini.ch/2010/08/sioug-conference-in-portoroz/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Oracle OpenWorld Schedule</title>
		<link>http://www.antognini.ch/2010/07/oracle-openworld-schedule/</link>
		<comments>http://www.antognini.ch/2010/07/oracle-openworld-schedule/#comments</comments>
		<pubDate>Tue, 13 Jul 2010 08:33:14 +0000</pubDate>
		<dc:creator>Christian Antognini</dc:creator>
				<category><![CDATA[Speaking]]></category>
		<category><![CDATA[TOP]]></category>

		<guid isPermaLink="false">http://antognini.ch/?p=1191</guid>
		<description><![CDATA[Back from two weeks of vacation I noticed that the schedule of the next OpenWorld is available here. The detailled information about my session, which is based on chapter 10 of my book, is the following: ID# S316683 Title Join Techniques Abstract This presentation explains how the query optimizer joins multiple sets of data to [...]]]></description>
			<content:encoded><![CDATA[<p>Back from two weeks of vacation I noticed that the schedule of the next OpenWorld is available here.</p>
<p>The detailled information about my session, which is based on chapter 10 of <a href="/top">my book</a>, is the following:</p>
<table>
<tr>
<td>ID#</td>
<td>S316683</td>
</tr>
<tr>
<td>Title</td>
<td>Join Techniques</td>
</tr>
<tr>
<td>Abstract</td>
<td>This presentation explains how the query optimizer joins multiple sets of data to each other. First it explains the operation of the basic join methods (nested loop, hash join, and merge join) and the possibilities we have to influence their performance. Then it presents some more advanced optimization techniques such as the transformations applied to joins, and partition-wise joins.</td>
</tr>
<tr>
<td>Track</td>
<td>Database</td>
</tr>
<tr>
<td>Date</td>
<td>22-SEP-2010</td>
</tr>
<tr>
<td>Time</td>
<td>13:00 &#8211; 14:00</td>
</tr>
<tr>
<td>Venue</td>
<td>Moscone South</td>
</tr>
<tr>
<td>Room</td>
<td>Rm 304</td>
</tr>
</table>
<p>I&#8217;m looking forward to seeing you in San Francisco!</p>
<p><strong>Update 2009-09-01</strong>: location was changed from &#8220;Rm 200&#8243; to &#8220;Rm 304&#8243;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.antognini.ch/2010/07/oracle-openworld-schedule/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Troubleshooting Oracle Performance &#8211; Downloadable Files</title>
		<link>http://www.antognini.ch/2010/06/troubleshooting-oracle-performance-downloadable-files-3/</link>
		<comments>http://www.antognini.ch/2010/06/troubleshooting-oracle-performance-downloadable-files-3/#comments</comments>
		<pubDate>Thu, 24 Jun 2010 09:29:38 +0000</pubDate>
		<dc:creator>Christian Antognini</dc:creator>
				<category><![CDATA[TOP]]></category>

		<guid isPermaLink="false">http://antognini.ch/?p=1171</guid>
		<description><![CDATA[This is just a short note to point out that I just uploaded a new version of the scripts related to TOP. The new ZIP is available through this page. The change log is the following: connect.sql Added DBM10205, DBA10205, DBM11201 and DBA11201 chapter02bind_variables.sql Because of 11g modified/added queries against V$SQL_SHARED_CURSOR chapter02sharable_cursors.sql Added SET SERVEROUTPUT [...]]]></description>
			<content:encoded><![CDATA[<p>This is just a short note to point out that I just uploaded a new version of the scripts related to <a href="/top">TOP</a>. The new ZIP is available through <a href="/top/downloadable-files">this page</a>.</p>
<p>The change log is the following:</p>
<table>
<tr>
<td>connect.sql                                 </td>
<td>Added DBM10205, DBA10205, DBM11201 and DBA11201</td>
</tr>
<tr>
<td>chapter02bind_variables.sql                </td>
<td>Because of 11g modified/added queries against V$SQL_SHARED_CURSOR</td>
</tr>
<tr>
<td>chapter02sharable_cursors.sql              </td>
<td>Added SET SERVEROUTPUT OFF in the initialization part</td>
</tr>
<tr>
<td>chapter03dbms_hprof.sql                    </td>
<td>New file</td>
</tr>
<tr>
<td>chapter03sql_trace_trigger.sql             </td>
<td>New file</td>
</tr>
<tr>
<td>chapter06display_awr.sql                   </td>
<td>Improved query that displays AWR content</td>
</tr>
<tr>
<td>chapter06execution_plans.sql               </td>
<td>Added example for UNION ALL (RECURSIVE WITH)</td>
</tr>
<tr>
<td>chapter07baseline_evolution_delete.sql     </td>
<td>New file</td>
</tr>
<tr>
<td>chapter07baseline_upgrade_11g.sql          </td>
<td>After import added update to set the owner of the SQL tuning set</td>
</tr>
<tr>
<td>chapter07opt_estimate.sql                  </td>
<td>Uncommented 11g query</td>
</tr>
<tr>
<td>chapter07outline_with_hj.sql               </td>
<td>Script compatible with 10g/11g (set &#8220;_hash_join_enabled&#8221;)</td>
</tr>
<tr>
<td>chapter07tune_last_statement.sql           </td>
<td>Added SET SERVEROUTPUT OFF in the initialization part</td>
</tr>
<tr>
<td>chapter08client-side_caching.sql           </td>
<td>New file</td>
</tr>
<tr>
<td>chapter09conditions.sql                    </td>
<td>Added queries containing NOT IN condition</td>
</tr>
<tr>
<td>chapter09hash_cluster.sql                  </td>
<td>Changed comment related to IN operator because of 11.2 improvement</td>
</tr>
<tr>
<td>chapter10hash_join.sql                     </td>
<td>Fixed typo in description</td>
</tr>
<tr>
<td>chapter10join_elimination.sql              </td>
<td>Fixed typo in description</td>
</tr>
<tr>
<td>chapter10join_elimination2.sql             </td>
<td>New file</td>
</tr>
<tr>
<td>chapter10pwj.sql                           </td>
<td>Disabled join-filter pruning</td>
</tr>
<tr>
<td>chapter10subquery_unnesting.sql            </td>
<td>Cover many more cases</td>
</tr>
<tr>
<td>chapter11ArrayInterface.java               </td>
<td>Added check for the return value of the executeBatch method</td>
</tr>
<tr>
<td>chapter11ArrayInterfacePerf.java           </td>
<td>Fixed number of iterations in main method</td>
</tr>
<tr>
<td>chapter11atomic_refresh.sql                </td>
<td>Changed CTAS to avoid ORA-30009</td>
</tr>
<tr>
<td>chapter11dpi_performance.sql               </td>
<td>Changed CTAS to avoid ORA-30009</td>
</tr>
<tr>
<td>chapter11px_auto_dop.sql                   </td>
<td>New file</td>
</tr>
<tr>
<td>chapter11px_ddl.sql                        </td>
<td>Changed the part displaying the parallel DDL status</td>
</tr>
<tr>
<td>chapter11px_dml.sql                        </td>
<td>Changed the part displaying the parallel DML status</td>
</tr>
<tr>
<td>chapter11px_query.sql                      </td>
<td>Changed the part displaying the parallel query status</td>
</tr>
<tr>
<td>chapter11result_cache_plsql.sql            </td>
<td>Added comment about invalidation in 11.2</td>
</tr>
<tr>
<td>chapter12data_compression.sql              </td>
<td>Changed CTAS to avoid ORA-30009</td>
</tr>
<tr>
<td>databasesDBA10205                          </td>
<td>New directory containing the files to create the database DBA10205</td>
</tr>
<tr>
<td>databasesDBM10205                          </td>
<td>New directory containing the files to create the database DBM10205</td>
</tr>
<tr>
<td>databasesDBA11201                          </td>
<td>New directory containing the files to create the database DBA11201</td>
</tr>
<tr>
<td>databasesDBM11201                          </td>
<td>New directory containing the files to create the database DBM11201</td>
</tr>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.antognini.ch/2010/06/troubleshooting-oracle-performance-downloadable-files-3/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Related-Combine Operation „UNION ALL (RECURSIVE WITH)“</title>
		<link>http://www.antognini.ch/2010/06/related-combine-operation-union-all-recursive-with/</link>
		<comments>http://www.antognini.ch/2010/06/related-combine-operation-union-all-recursive-with/#comments</comments>
		<pubDate>Thu, 10 Jun 2010 06:53:37 +0000</pubDate>
		<dc:creator>Christian Antognini</dc:creator>
				<category><![CDATA[11gR2]]></category>
		<category><![CDATA[Query Optimizer]]></category>
		<category><![CDATA[TOP]]></category>

		<guid isPermaLink="false">http://antognini.ch/?p=1160</guid>
		<description><![CDATA[To make easier the interpretation of execution plans, in chapter 6 of TOP I defined three types of operations: standalone operations, unrelated-combine operations, and related-combine operations. For combine operations I also added a list of all operations of each type. Since in 11.2 a new related-combine operation is available, I decided to write this short [...]]]></description>
			<content:encoded><![CDATA[<p>To make easier the interpretation of execution plans, in chapter 6 of <a href="/top">TOP</a> I defined three types of operations: standalone operations, unrelated-combine operations, and related-combine operations. For combine operations I also added a list of all operations of each type. Since in 11.2 a new related-combine operation is available, I decided to write this short post as addenda to the content of the book.</p>
<p>The new related-combine operation, named “UNION ALL (RECURSIVE WITH)”, is available to support the new recursive <a href="http://download.oracle.com/docs/cd/E11882_01/server.112/e10592/statements_10002.htm#i2077142">subquery factoring clause</a>. Hence, it is used for hierarchical queries. The following query and its execution plan show an example:</p>
<pre>SQL> WITH
  2    e (xlevel, empno, ename, job, mgr, hiredate, sal, comm, deptno)
  3    AS (
  4      SELECT 1, empno, ename, job, mgr, hiredate, sal, comm, deptno
  5      FROM emp
  6      WHERE mgr IS NULL
  7      UNION ALL
  8      SELECT mgr.xlevel+1, emp.empno, emp.ename, emp.job, emp.mgr, emp.hiredate, emp.sal, emp.comm, emp.deptno
  9      FROM emp, e mgr
 10      WHERE emp.mgr = mgr.empno
 11    )
 12  SELECT *
 13  FROM e;

-------------------------------------------------------------------------------
| Id  | Operation                                 | Name    | Starts | A-Rows |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                          |         |      1 |     14 |
|   1 |  VIEW                                     |         |      1 |     14 |
|   2 |   UNION ALL (RECURSIVE WITH) BREADTH FIRST|         |      1 |     14 |
|*  3 |    TABLE ACCESS FULL                      | EMP     |      1 |      1 |
|   4 |    NESTED LOOPS                           |         |      4 |     13 |
|   5 |     NESTED LOOPS                          |         |      4 |     13 |
|   6 |      RECURSIVE WITH PUMP                  |         |      4 |     14 |
|*  7 |      INDEX RANGE SCAN                     | EMP_MGR |     14 |     13 |
|   8 |     TABLE ACCESS BY INDEX ROWID           | EMP     |     13 |     13 |
-------------------------------------------------------------------------------

   3 - filter("MGR" IS NULL)
   7 - access("EMP"."MGR"="MGR"."EMPNO")
       filter("EMP"."MGR" IS NOT NULL)</pre>
<p>Notice that there are actually two operations:</p>
<ul>
<li>UNION ALL (RECURSIVE WITH) BREADTH FIRST</li>
<li>UNION ALL (RECURSIVE WITH) DEPTH FIRST</li>
</ul>
<p>As their name suggest, the difference is due to the <a href="http://download.oracle.com/docs/cd/E11882_01/server.112/e10592/statements_10002.htm#BCEDDGGE">search clause</a> that you can set to either BREADTH FIRST BY or DEPTH FIRST BY.</p>
<p>Reading an execution plan containing the “UNION ALL (RECURSIVE WITH)” operation is the same as reading one containing the “CONNECT BY WITH FILTERING” operation. As a matter of fact, the purpose of both operations is basically the same. Just notice that also the “PUMP” operation used in the execution plan differs. While in the former it is called “RECURSIVE WITH PUMP”, in the latter it is called “CONNECT BY PUMP”. But the difference, for the purpose of reading the execution plan, does not matter.</p>
<p>You find a full description on how to read such an execution plan in <a href="/2008/06/operation-connect-by-with-filtering/">this post</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.antognini.ch/2010/06/related-combine-operation-union-all-recursive-with/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Ad: Optimizing Oracle Performance Seminar in Berlin</title>
		<link>http://www.antognini.ch/2010/05/ad-optimizing-oracle-performance-seminar-in-berlin/</link>
		<comments>http://www.antognini.ch/2010/05/ad-optimizing-oracle-performance-seminar-in-berlin/#comments</comments>
		<pubDate>Sat, 22 May 2010 09:24:10 +0000</pubDate>
		<dc:creator>Christian Antognini</dc:creator>
				<category><![CDATA[Speaking]]></category>
		<category><![CDATA[TOP]]></category>

		<guid isPermaLink="false">http://antognini.ch/?p=1104</guid>
		<description><![CDATA[In one month I will be in Berlin presenting a two-day seminar based on the chapters 1, 2, 8, 9, 10 and 11 of my book. The event is organized by DOAG. You can read the full description of the seminar (incl. agenda) here. Just be careful that the spoken language will be German (slides [...]]]></description>
			<content:encoded><![CDATA[<p>In one month I will be in Berlin presenting a two-day seminar based on the chapters 1, 2, 8, 9, 10 and 11 of my <a href="/top">book</a>. The event is organized by <a href="http://www.doag.org">DOAG</a>. You can read the full description of the seminar (incl. agenda) <a href="http://mydoag.doag.org/termine/termine.php?tid=400117">here</a>. Just be careful that the spoken language will be German (slides will be in English, though). Since I was just informed that there are less than ten free seats, do not wait to long if you want to join us&#8230; </p>
]]></content:encoded>
			<wfw:commentRss>http://www.antognini.ch/2010/05/ad-optimizing-oracle-performance-seminar-in-berlin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

