<?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; pagination</title>
	<atom:link href="https://blog.developpez.com/pachot/tag/pagination/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>Requêtes de pagination &#8216;Top-N&#8217;</title>
		<link>https://blog.developpez.com/pachot/11g_row_limiting/</link>
		<comments>https://blog.developpez.com/pachot/11g_row_limiting/#comments</comments>
		<pubDate>Tue, 25 Jun 2013 17:51:58 +0000</pubDate>
		<dc:creator><![CDATA[pachot]]></dc:creator>
				<category><![CDATA[MicroLearning]]></category>
		<category><![CDATA[first_rows]]></category>
		<category><![CDATA[pagination]]></category>
		<category><![CDATA[rownum]]></category>
		<category><![CDATA[Top-N]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/pachot/?p=256</guid>
		<description><![CDATA[On a souvent besoin d&#8217;afficher la première page d&#8217;un résultat (par exemple les 10 premières lignes) et éventuellement les pages suivantes avec des requêtes indépendantes. En attendant la 12c (très bientôt) qui implémentera la syntaxe standard qui commence à se &#8230; <a href="https://blog.developpez.com/pachot/11g_row_limiting/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>On a souvent besoin d&rsquo;afficher la première page d&rsquo;un résultat (par exemple les 10 premières lignes) et éventuellement les pages suivantes avec des requêtes indépendantes. En attendant la 12c (très bientôt) qui implémentera la syntaxe standard qui commence à se normaliser sur tous les SGBD (OFFSET &#8230; FETCH FIRST/NEXT &#8230; ROWS)  il y a plusieurs techniques possibles mais toutes n&rsquo;ont pas les mêmes performances.</p>
<p><ins datetime="2013-06-11T10:29:02+00:00">La démo des différentes possibilités avec plans d&rsquo;exécution: <a href="http://ora-demo.pachot.net/11g_row_limiting.html" title="demo" target="_blank">demo</a></ins></p>
<p>Déjà commençons avec deux mauvaises idées:</p>
<ul>
<li>Ne pas mettre d&rsquo;ORDER BY en espérant que le résultat revient trié.<br />
Sans ORDER BY, l&rsquo;ordre du résultat n&rsquo;est pas prédictible. Même s&rsquo;il on passe par un index. Il faut mettre la clause ORDER BY et le tri sera évité par Oracle si l&rsquo;index correspondant le permet.</li>
<li>Faire une requête normale (avec ORDER BY) et ne limiter le résultat qu&rsquo;au moment du Fetch.<br />
Le résultat sera juste, mais les performances moins bonne que si l’optimiseur connait à l&rsquo;avance le nombre de lignes dont on a besoin.(cf. <a href="http://dl.dropboxusercontent.com/u/2326391/pachot.net/ora-demo/11g_row_limiting.html#8.1" title="plans">plans</a>)</li>
</ul>
<p><strong>rownum</strong><br />
La technique la plus ancienne est de faire le ORDER BY dans une sous-requêtes, puis limiter le résultat avec ROWNUM:<br />
Exemple:<br />
les 10 premiers enregistrements d&rsquo;un contrat:</p>
<pre>select * from (select * from TEST where contract_id=500 order by start_validity  asc) where rownum&lt;=10;</pre>
<p>C&rsquo;est la solution qui fonctionne depuis longtemps et probablement la plus utilisée (par Hibernate par exemple).</p>
<p>Mais la doc 11gR2 précise cependant: <em>The ROW_NUMBER built-in SQL function provides superior support for ordering the results of a query</em></p>
<p><strong>row_number()</strong><br />
Avec la fonction analytique row_number() on compte les lignes dans une sous-requête puis on limite le résultat.</p>
<pre>select /*+ FIRST_ROWS */ * from (select test.*,row_number()over(order by start_validity) rn from test where contract_id=500) where rn&lt;=10  order by start_validity;</pre>
<p>A noter:</p>
<p>&#8211; je lance la requête en FIRST ROWS car je je souhaite afficher rapidement ces 10 premières lignes. Avec ROWNUM, c&rsquo;était implicite &#8211; le CBO passait en optimisation FIRST_ROWS(10). L&rsquo;accès par INDEX RANGE SCAN est donc probablement préférable.</p>
<p>&#8211; j&rsquo;ai utilisé FIRST_ROWS et non FIRST_ROWS(10) car sinon dans mon exemple, FULL TABLE SCAN était choisi (peut être un bug en 11.2.0.3). La bonne technique devrait être FIRST_ROWS(n).</p>
<p>&#8211; j&rsquo;ai un index sur (contract_id,start_validity) qui peut être utilisé pour éviter un tri car ce sont des NUMBER. Avec des VARCHAR2 le plan d&rsquo;exécution peut dépendre des paramètres NLS car l&rsquo;ordre de l&rsquo;index (binary) n&rsquo;est peut-être pas le même que celui de la langue.</p>
<p>Le conseil: tester et vérifier les plans d&rsquo;exécution et le volume nécessaire au tri sur des données représentatives afin de valider les hints et indexes.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
