<?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>Oracle - Concepts et Exemples &#187; Transformation</title>
	<atom:link href="https://blog.developpez.com/pachot/tag/transformation/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/pachot</link>
	<description>Les fonctionalités et concepts d&#039;Oracle à partir de traductions et de démos</description>
	<lastBuildDate>Sun, 03 Apr 2016 20:36:21 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.42</generator>
	<item>
		<title>12c: la transformation Partial Join Evaluation</title>
		<link>https://blog.developpez.com/pachot/12c_partial_join_evaluation/</link>
		<comments>https://blog.developpez.com/pachot/12c_partial_join_evaluation/#comments</comments>
		<pubDate>Tue, 01 Oct 2013 19:43:32 +0000</pubDate>
		<dc:creator><![CDATA[pachot]]></dc:creator>
				<category><![CDATA[12c]]></category>
		<category><![CDATA[Hash Join Semi]]></category>
		<category><![CDATA[Partial join evaluation]]></category>
		<category><![CDATA[PJE]]></category>
		<category><![CDATA[Transformation]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/pachot/?p=800</guid>
		<description><![CDATA[Faut-il remplacer les jointures par des EXISTS lorsque c&#8217;est possible ? Une sous-requête EXISTS n&#8217;a pas besoin de ramener toutes les lignes d&#8217;une jointure: dès qu&#8217;il y a une correspondance pour une valeur de la jointure, on peut passer à &#8230; <a href="https://blog.developpez.com/pachot/12c_partial_join_evaluation/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Faut-il remplacer les jointures par des EXISTS lorsque c&rsquo;est possible ?<br />
Une sous-requête EXISTS n&rsquo;a pas besoin de ramener toutes les lignes d&rsquo;une jointure: dès qu&rsquo;il y a une correspondance pour une valeur de la jointure, on peut passer à la suivante. C&rsquo;est un Semi Hash Join, qui est plus rapide qu&rsquo;un Hash Join. Très souvent le CBO va faire cette réécriture lors des transformations de la phase d&rsquo;optimisation.<br />
En en 12c on a une transformation automatique de plus lorsque les lignes de la jointure seront au final dédoublonnées avec un DISTINCT.</p>
<p>Par exemple, la requête suivante:</p>
<pre>select distinct status_label from TEST_STATUS 
 join TEST using(status_id) where flag='Y';</pre>
<p>sera transformée en:</p>
<pre>select status_label from TEST_STATUS 
where exists(
 select null from TEST 
 where flag='Y' and TEST.status_id=TEST_STATUS.status_id
);</pre>
<p>vu qu&rsquo;on ne renvoit que les colonnes de TEST_STATUS, un EXISTS (ou IN) est suffisant. Et on obtient le plan d&rsquo;exécution suivant:</p>
<pre>------------------------------------------------------------------------------------------------------------------------
| Id  | Operation           | Name        | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |             |      1 |        |     10 |00:00:00.01 |       7 |       |       |          |
|   1 |  HASH UNIQUE        |             |      1 |     10 |     10 |00:00:00.01 |       7 |  1214K|  1214K| 1105K (0)|
|*  2 |   HASH JOIN SEMI    |             |      1 |     10 |     10 |00:00:00.01 |       7 |  1185K|  1185K| 1142K (0)|
|   3 |    TABLE ACCESS FULL| TEST_STATUS |      1 |     10 |     10 |00:00:00.01 |       3 |       |       |          |
|*  4 |    TABLE ACCESS FULL| TEST        |      1 |  50000 |     10 |00:00:00.01 |       4 |       |       |          |
------------------------------------------------------------------------------------------------------------------------</pre>
<p>Ici on voit le gros avantage dans la colonne A-Rows: le Full Table Scan de la table TEST qui fait 100000 lignes, s&rsquo;est arrêté dès qu&rsquo;on a trouvé les 10 correspondances avec la table TEST_STATUS. Pas besoin de continuer: le prédicat EXISTS est vérifié.<br />
C&rsquo;est le HASH JOIN SEMI qui fait ça alors qu&rsquo;un HASH JOIN aurait lu 100000 lignes et renvoyé 50000 lignes jusqu&rsquo;au DISTINCT. </p>
<p>Voici le plan en désactivant les transformations:</p>
<pre>------------------------------------------------------------------------------------------------------------------------
| Id  | Operation           | Name        | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |             |      1 |        |     10 |00:00:00.09 |     214 |       |       |          |
|   1 |  HASH UNIQUE        |             |      1 |     10 |     10 |00:00:00.09 |     214 |  1214K|  1214K| 1099K (0)|
|*  2 |   HASH JOIN         |             |      1 |  50000 |    100K|00:00:00.07 |     214 |  1185K|  1185K| 1129K (0)|
|   3 |    TABLE ACCESS FULL| TEST_STATUS |      1 |     10 |     10 |00:00:00.01 |       3 |       |       |          |
|*  4 |    TABLE ACCESS FULL| TEST        |      1 |  50000 |    100K|00:00:00.01 |     211 |       |       |          |
------------------------------------------------------------------------------------------------------------------------</pre>
<p>A noter que en 11.2 il y avait déjà une transformation utile dans ce cas, Distinct Placement qui fait descendre le DISTINCT sous la jointure, mais qui nécessite quand même de lire toute la table.</p>
<p><ins datetime="2013-10-01T18:59:10+00:00">Demo, hints, plans d&rsquo;exécution et traces 10053 complétes dans la <a href="http://ora-demo.pachot.net/12c_partial_join_evaluation.html" title="demo" target="_blank">demo</a></ins></p>
<p>Alors pourquoi faire ça plutôt que de réécrire la requête ? Le gros intérêt de ces transformations, c&rsquo;est lorsqu&rsquo;on on fait une requête sur une vue dans laquelle il y a la jointure. La vue va souvent chercher des colonnes dont on a pas besoin. Les transformations permettent alors d&rsquo;éliminer les opérations inutiles.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
