--- /dev/null
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
+[
+ <!ENTITY in "<small style='font-size:small'>∈</small>">
+ <!ENTITY notin "<small style='font-size:small'>∉</small>">
+ <!ENTITY mapsto "↦">
+ <!ENTITY join "⨝">
+]
+ >
+<html xmlns="http://www.w3.org/1999/xhtml" >
+ <head>
+ <title>Prise en main de Postgresql</title>
+
+ <meta http-equiv="Content-Type"
+ content="text/html; charset=utf-8" />
+ <meta name="copyright"
+ content="Copyright © 2013 Kim Nguyễn" />
+
+ <!-- Load jQuery -->
+ <script src="../jquery-2.0.3.min.js" type="text/javascript" ></script>
+ <script src="../libs/raphael-min.js" type="text/javascript" ></script>
+ <!-- Load the library -->
+ <script src="../simpleWebSlides.js" type="text/javascript" ></script>
+
+ <link rel="stylesheet" href="../simpleWebSlides.css" type="text/css" media="all" />
+ <!-- Load a custom Theme, the class-element marks this style-sheet
+ a "theme" that can be swtiched dynamicaly -->
+ <link class="sws-theme" rel="stylesheet" title="U-Psud style" href="../themes/uPsud.css" type="text/css" />
+
+ <!-- Customize some templates and initialize -->
+
+ <script type="text/javascript">
+ SWS.Config['sws-slide-change'] = SWS.Effects.slideChangeFadeOutIn;
+ SWS.Config['sws-object-deactivate'] = SWS.Effects.objectDeactivateFadeOut;
+ SWS.Config['sws-object-activate'] = SWS.Effects.objectActivateFadeIn;
+
+ //Ensures that we load SWS at the very end, after MathJax has
+ //been initialized
+
+ $(window).load(SWS.Presentation.init);
+ </script>
+ </head>
+ <body>
+ <a href="bd05.xhtml" class="sws-previous"/>
+ <div class="sws-slide sws-cover sws-option-nofooter">
+ <h1>Bases de données</h1>
+ <h3>Polytech Paris-Sud</h3>
+ <h3>Apprentis 4<sup>ème</sup> année</h3>
+ <h1>Cours 6 : Prise en main de Postgresql</h1>
+ <a href="mailto:kn@lri.fr">kn@lri.fr</a><br/>
+ <a href="http://www.lri.fr/~kn/">http://www.lri.fr/~kn</a>
+ </div>
+
+ <h1>Base d'exemple</h1>
+ <div class="sws-slide">
+ <h1>On considère la base d'exemple suivante</h1>
+<code>
+ CREATE TABLE PEOPLE (<u>pid INTEGER PRIMARY key</u>,
+ firstname VARCHAR(30),
+ lastname VARCHAR(30));
+
+ CREATE TABLE MOVIE (<u>mid INTEGER PRIMARY KEY</u>,
+ title VARCHAR(90) NOT NULL,
+ year INTEGER NOT NULL,
+ runtime INTEGER NOT NULL,
+ rank INTEGER NOT NULL);
+
+ CREATE TABLE ROLE (mid INTEGER REFERENCES MOVIE,
+ pid INTEGER REFERENCES PEOPLE,
+ name VARCHAR(70),
+ <u>PRIMARY KEY(mid, pid, name)</u>);
+
+ CREATE TABLE DIRECTOR (mid INTEGER REFERENCES MOVIE,
+ pid INTEGER REFERENCES PEOPLE,
+ <u>PRIMARY KEY (mid, pid)</u>);
+</code>
+ </div>
+<h1>EXPLAIN</h1>
+<div class="sws-slide">
+<h1>EXPLAIN ANALYSE</h1>
+<p>On peut demander à Postgresql d'afficher le plan qu'il calcule pour
+ une requête avec les esitmations de coût :
+</p>
+<code> <u>EXPLAIN</u> requête; </code>
+<p>Dans ce cas, la requête n'est pas évaluée. On peut aussi évaluer la
+ requête :</p>
+<code> <u>EXPLAIN ANALYSE</u> requête; </code>
+<p>Dans ce cas, la requête est évaluée et les coût réels sont
+ affichés. S'ils divergent des coûts estimés, l'optimiseur s'est
+ trompé, par exemple parce que ses statistiques ne sont pas à
+ jour</p>
+
+</div>
+
+<div class="sws-slide">
+<h1>EXPLAIN ANALYSE (suite)</h1>
+<p>On considère: </p>
+<code>
+ EXPLAIN ANALYSE SELECT * FROM ROLE,PEOPLE WHERE
+ ROLE.pid = PEOPLE.pid;
+</code>
+<p>On obtient :</p>
+<code> Hash Join (cost=312.07..822.95 rows=14535 width=37)
+ (actual time=14.799..44.691 rows=14535 loops=1)
+ Hash Cond: (role.pid = people.pid)
+ -> Seq Scan on role (cost=0.00..238.35 rows=14535 width=20)
+ (actual time=0.019..7.570 rows=14535 loops=1)
+ -> Hash (cost=175.92..175.92 rows=10892 width=17)
+ (actual time=14.711..14.711 rows=10892 loops=1)
+ -> Seq Scan on people (cost=0.00..175.92 rows=10892 width=17)
+ (actual time=0.015..5.944 rows=10892 loops=1)
+</code>
+</div>
+<div class="sws-slide">
+<h1>EXPLAIN ANALYSE (suite)</h1>
+<code>
+<u>Seq Scan</u> on people <a>(cost=0.00..175.92 rows=10892 width=17)</a>
+ <s>(actual time=0.015..5.944 rows=10892 loops=1)</s>
+</code>
+<ul>
+<li><u>Le nom de l'opérateur</u> ≡ nœud de l'arbre dans le plan de
+ requête</li>
+<li><a>Estimation du coût</a> (voir suite)</li>
+<li><s>Coût réel</s> n'apparaît que si on a fait <tt>EXPLAIN
+ ANALYSE</tt> (voir suite)</li>
+</ul>
+</div>
+<div class="sws-slide">
+<h1>Estimation des coût</h1>
+<code>
+ (<a>cost=0.00..175.92</a> <u>rows=10892</u> <s>width=17</s>)
+</code>
+<ul>
+<li><a>Estimation du coût</a>. Unité : temps que met une lecture de
+ bloc de 8ko (pour être indépendant du hardware). Le premier nombre
+ est le temps estimé pour avoir le premier résultat. Le deuxième le
+ temps estimé pour avoir l'ensemble.
+</li>
+<li><u>Estimation du nombre de lignes</u> dans le résultat</li>
+<li><s>Taille des lignes en octets</s> </li>
+</ul>
+</div>
+<div class="sws-slide">
+<h1>Coût réel</h1>
+<code>
+ (<a>actual time=0.015..5.944</a> <u>rows=10892</u> <s>loops=1</s>)
+</code>
+<ul>
+<li><a>Coût réel</a>. Unité : <a>ms</a>. Devrait être proportionnel à
+ l'estimation si l'optimiseur ne s'est pas trompé. Le premier nombre
+ est le temps pour avoir le premier résultat. Le deuxième le
+ temps pour avoir l'ensemble.
+</li>
+<li><u>Nombre de lignes</u> dans le résultat</li>
+<li><s>looks=x</s> l'opérateur a été appelé x fois</li>
+</ul>
+</div>
+<div class="sws-slide">
+<h1>Lecture du plan de requête </h1>
+<code>
+ <u>Hash Join</u> (cost=…) (actual time=…)
+ <u>Hash Cond</u>: (role.pid = people.pid)
+ <u>-></u> <s>Seq Scan</s> on role (cost=…) (actual time=…)
+ <u>-></u> <a>Hash</a> (cost=…) (actual time=…)
+ <a>-></a> <em style="color:orange">Seq Scan</em> on people (cost=…) (actual time=…)
+
+</code>
+<p style="text-align:center;">
+<img style="width:70%" src="explain_plan.svg" alt="explain" />
+</p>
+<p>Note: les projections n'apparaissent pas, on peut les voir
+ avec <tt>EXPLAIN ANALYSE VERBOSE</tt>.</p>
+</div>
+<h1>Exemples d'opérateurs</h1>
+<div class="sws-slide">
+<h1>Nœuds fréquements rencontrés lors d'un EXPLAIN ANALYSE</h1>
+<p>Les opérateurs sont déclinés selon les différents algorithmes
+ (jointure, tris, …)</p>
+<ul>
+<li><tt>Seq Scan</tt>: Scan séquentiel</li>
+<li><tt>Nested loop</tt>: Jointure itérative page à page</li>
+<li><tt>Merge sort join</tt>: Jointure par tri fusion</li>
+<li><tt>Hash join</tt>: jointure par hashage (généralisation de la
+ jointure sur index)</li>
+<li><tt>Sort</tt>: Tri (le nœud indique l'algo de tri et la fonction
+ de comparaison)</li>
+<li><tt>Index scan</tt>: scan d'un index (précise l'index et la condition)</li>
+<li><tt>Hash</tt>: génération d'une table de hash à la volée</li>
+<li><tt>Bitmap Index scan/Bitmap heap scan</tt>: génération et
+ utilisation d'un index bitmap à la volée (voire suite)</li>
+<li><tt>Materialize</tt>: écriture de résultats intermédiaires sur le disque</li>
+</ul>
+
+
+</div>
+<div class="sws-slide">
+<h1>Retour sur les opératuers « <i>Bitmap</i> »</h1>
+<p>(Cours 5) si l'index est non-groupant, l'utilisation de l'index
+ peut provoquer une séquence de chargement/déchargement de pages
+ ruinant les performances
+</p>
+<p>Solution en deux phases</p>
+<ul>
+ <li>Scanner l'index et créer un bitmap de taille N où N est le
+ nombre de pages de la relation. Pour chaque entrée d'index
+ satisfaisant le résultat, mettre le bit correspondant à 1 (phase
+ Bitmap Index Scan)
+ </li>
+ <li>
+ Parcourir la relation dans l'ordre du disque, page à page. Si la
+ page est à 1 dans le bitmap, on la charge, sinon on l'ignore.
+ Une fois la page chargée il faut <u>réévaluer la condition</u> car on
+ a oublié quels étaients les résultats de l'index (phase Bitmap
+ Heap Scan)
+ </li>
+</ul>
+<p>Intéret: Un bitmap est petit (si la relation contient 10000 pages,
+ le bitmap contient 10000 bits ou environs 1250 octets (soit moins
+ d'une page).</p>
+<p>Cela permet aussi de répondre efficacement aux requêtes
+ booléenes complexes (i.e. autre qu <tt>AND</tt>). En effet on
+ calcule un bitmap pour chaque sous-condition, et on fait les
+ opérations entre bitmap bit à bit.
+</p>
+</div>
+<h1>Démo</h1>
+</body>
+</html>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="330.31494"
+ height="124.87304"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.4 r9939"
+ sodipodi:docname="explain_plan.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="2.9145596"
+ inkscape:cx="52.450126"
+ inkscape:cy="82.881477"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:snap-global="true"
+ fit-margin-top="3"
+ fit-margin-left="3"
+ fit-margin-right="3"
+ fit-margin-bottom="3"
+ inkscape:window-width="1631"
+ inkscape:window-height="1026"
+ inkscape:window-x="1249"
+ inkscape:window-y="407"
+ inkscape:window-maximized="1"
+ units="pt">
+ <inkscape:grid
+ type="xygrid"
+ id="grid2985"
+ empspacing="5"
+ visible="true"
+ enabled="true"
+ snapvisiblegridlinesonly="true"
+ originx="-107.10693px"
+ originy="-818.75391px" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-107.10693,-108.73524)">
+ <g
+ id="g3081"
+ transform="translate(0,-1.3320312e-6)"
+ style="fill:#ec1100;fill-opacity:1">
+ <text
+ sodipodi:linespacing="125%"
+ id="text2987"
+ y="192.36218"
+ x="160"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ec1100;fill-opacity:1;stroke:none;font-family:Sans"
+ xml:space="preserve"><tspan
+ y="192.36218"
+ x="160"
+ id="tspan2989"
+ sodipodi:role="line">Role</tspan></text>
+ <text
+ sodipodi:linespacing="125%"
+ id="text2991"
+ y="192.36218"
+ x="285"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ec1100;fill-opacity:1;stroke:none;font-family:Sans"
+ xml:space="preserve"><tspan
+ y="192.36218"
+ x="285"
+ id="tspan2993"
+ sodipodi:role="line" /></text>
+ </g>
+ <g
+ id="g3075"
+ transform="translate(-15.6665,-19.516785)"
+ style="fill:#14437c;fill-opacity:1">
+ <text
+ sodipodi:linespacing="125%"
+ id="text2995"
+ y="147.36218"
+ x="215"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#14437c;fill-opacity:1;stroke:none;font-family:Sans"
+ xml:space="preserve"><tspan
+ style="font-size:32px;fill:#14437c;fill-opacity:1"
+ y="147.36218"
+ x="215"
+ id="tspan2997"
+ sodipodi:role="line">⨝</tspan></text>
+ <text
+ sodipodi:linespacing="125%"
+ id="text3001"
+ y="152.36218"
+ x="235"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#14437c;fill-opacity:1;stroke:none;font-family:Sans"
+ xml:space="preserve"><tspan
+ style="font-size:10px;fill:#14437c;fill-opacity:1"
+ y="152.36218"
+ x="235"
+ id="tspan3003"
+ sodipodi:role="line">role.pid = people.pid</tspan></text>
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="254.32658"
+ y="112.34022"
+ id="text3013"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3015"
+ x="254.32658"
+ y="112.34022" /></text>
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 185,177.36218 50,-40"
+ id="path3087"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 300,177.36218 -45,-40"
+ id="path3089"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <g
+ id="g3109"
+ transform="translate(-5.3601685,0.84391091)">
+ <text
+ sodipodi:linespacing="125%"
+ id="text3095"
+ y="156.85809"
+ x="341.37579"
+ style="font-size:13px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ xml:space="preserve"><tspan
+ y="156.85809"
+ x="341.37579"
+ sodipodi:role="line"
+ id="tspan3073" /></text>
+ <text
+ sodipodi:linespacing="125%"
+ id="text3101"
+ y="121.51828"
+ x="340.36017"
+ style="font-size:13px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ xml:space="preserve"><tspan
+ y="121.51828"
+ x="340.36017"
+ id="tspan3103"
+ sodipodi:role="line">Hash Join join</tspan></text>
+ <text
+ sodipodi:linespacing="125%"
+ id="text3105"
+ y="84.462944"
+ x="340.36017"
+ style="font-size:13px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ xml:space="preserve"><tspan
+ y="84.462944"
+ x="340.36017"
+ id="tspan3107"
+ sodipodi:role="line" /></text>
+ </g>
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 305.20937,216.41809 0,-25"
+ id="path3091-5"
+ inkscape:connector-curvature="0" />
+ <text
+ xml:space="preserve"
+ style="font-size:13px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="110"
+ y="192.36218"
+ id="text3081-9"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ x="110"
+ y="192.36218"
+ id="tspan3089-4">Scan</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#8bb400;fill-opacity:1;stroke:none;font-family:URW Bookman L;-inkscape-font-specification:URW Bookman L"
+ x="300"
+ y="187.36218"
+ id="text3049"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3051"
+ x="300"
+ y="187.36218"
+ style="font-size:20px;font-weight:bold;-inkscape-font-specification:URW Bookman L Bold;fill:#8bb400;fill-opacity:1">#</tspan></text>
+ <g
+ id="g3081-2"
+ transform="translate(95.000001,34.999999)"
+ style="fill:#ff7f00;fill-opacity:1">
+ <text
+ sodipodi:linespacing="125%"
+ id="text2987-2"
+ y="192.36218"
+ x="195"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ff7f00;fill-opacity:1;stroke:none;font-family:Sans"
+ xml:space="preserve"><tspan
+ y="192.36218"
+ x="195"
+ id="tspan2989-7"
+ sodipodi:role="line">People</tspan></text>
+ <text
+ sodipodi:linespacing="125%"
+ id="text2991-1"
+ y="192.36218"
+ x="285"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ff7f00;fill-opacity:1;stroke:none;font-family:Sans"
+ xml:space="preserve"><tspan
+ y="192.36218"
+ x="285"
+ id="tspan2993-5"
+ sodipodi:role="line" /></text>
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-size:13px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="350"
+ y="227.36218"
+ id="text3081-9-4"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ x="350"
+ y="227.36218"
+ id="tspan3089-4-5">Scan</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:URW Bookman L;-inkscape-font-specification:URW Bookman L"
+ x="284.09094"
+ y="106.9535"
+ id="text3108"
+ sodipodi:linespacing="125%"
+ transform="translate(50.417285,74.609394)"><tspan
+ sodipodi:role="line"
+ id="tspan3110"
+ x="284.09094"
+ y="106.9535" /></text>
+ <g
+ id="g3109-6"
+ transform="translate(-15.360168,60.843901)">
+ <text
+ sodipodi:linespacing="125%"
+ id="text3095-3"
+ y="156.85809"
+ x="341.37579"
+ style="font-size:13px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ xml:space="preserve"><tspan
+ y="156.85809"
+ x="341.37579"
+ sodipodi:role="line"
+ id="tspan3073-9" /></text>
+ <text
+ sodipodi:linespacing="125%"
+ id="text3101-1"
+ y="121.51828"
+ x="340.36017"
+ style="font-size:13px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ xml:space="preserve"><tspan
+ y="121.51828"
+ x="340.36017"
+ id="tspan3103-8"
+ sodipodi:role="line">Table de hash en</tspan><tspan
+ y="137.76828"
+ x="340.36017"
+ sodipodi:role="line"
+ id="tspan3148">mémoire</tspan></text>
+ <text
+ sodipodi:linespacing="125%"
+ id="text3105-9"
+ y="84.462944"
+ x="340.36017"
+ style="font-size:13px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ xml:space="preserve"><tspan
+ y="84.462944"
+ x="340.36017"
+ id="tspan3107-3"
+ sodipodi:role="line" /></text>
+ </g>
+ </g>
+</svg>