root/traduc/branches/bv803/manuel/arch-dev.sgml

Revision 13, 26.2 kB (checked in by gleu, 3 years ago)

Suite de l'import pour le passage CVS à SVN.

Line 
1 <!--
2 $Header: /var/lib/cvs/pgsql-fr/sgml/arch-dev.sgml,v 1.13 2005/07/15 06:14:19 guillaume Exp $
3 -->
4
5  <chapter id="overview">
6   <title>Présentation des mécanismes internes de PostgreSQL</title>
7
8   <note>
9    <title>Auteur</title>
10    <para>
11     Ce chapitre vient originellement de <xref linkend="SIM98">, la thèse de
12     Stefan Simkovics préparée à l'université de technologie de Vienne sous la
13     direction du Dr. Georg Gottlob et de son assistante Katrin Seyr.
14    </para>
15   </note>
16
17   <para>
18    Ce chapitre présente la structure interne du serveur
19    <productname>PostgreSQL</productname>. Après avoir lu les sections suivantes,
20    vous devriez avoir une idée sur la façon dont une requête est exécutée. Ce
21    chapitre n'a pas pour but de donner une description détaillée des opérations
22    internes de <productname>PostgreSQL</productname> car un tel document
23    serait énorme. À la place, ce chapitre a pour but d'aider le lecteur à
24    comprendre la suite générale des opérations arrivant au niveau serveur à
25    partir du moment où une requête est reçue jusqu'au moment où les résultats
26    sont renvoyés au client.
27   </para>
28
29   <sect1 id="query-path">
30    <title>Chemin d'une requête</title>
31
32    <para>
33     Ici, nous allons donner un rapide aperçu des étapes qu'une requête doit
34     franchir pour obtenir un résultat.
35    </para>
36
37    <procedure>
38     <step>
39      <para>
40       Une connexion doit être établie à partir d'une application au serveur
41       <productname>PostgreSQL</productname>. L'application transmet une requête
42       au serveur et attend de recevoir les résultats renvoyés par le serveur.
43      </para>
44     </step>
45
46     <step>
47      <para>
48       L'<firstterm>étape de l'analyse</firstterm> vérifie la requête transmise
49       par l'application au niveau de la syntaxe et crée un <firstterm>arbre
50       représentant la requête</firstterm>.
51      </para>
52     </step>
53
54     <step>
55      <para>
56       Le <firstterm>système de réécriture</firstterm> prend l'arbre représentant
57       la requête et cherche les <firstterm>règles</firstterm> (stockées dans les
58       <firstterm>catalogues système</firstterm>) à appliquer à l'arbre de la
59       requête. Il exécute les transformations données dans les <firstterm>corps
60       des règles</firstterm>.
61      </para>
62
63      <para>
64       Une application du système de réécriture est la réalisation des
65       <firstterm>vues</firstterm>. À chaque fois qu'une requête comprenant une
66       vue (c'est-à-dire une <firstterm>table virtuelle</firstterm>) est exécutée,
67       le système de réécriture modifie la requête de l'utilisateur par la
68       <firstterm>définition de la vue</firstterm>, c'est-à-dire une requête qui
69       accède aux <firstterm>tables de base</firstterm>.
70      </para>
71     </step>
72
73     <step>
74      <para>
75       Le <firstterm>planificateur/optimiseur</firstterm> prend l'arbre
76       (réécrit) de la requête et crée un <firstterm>plan
77       d'exécution</firstterm> qui sera l'entrée de
78       l'<firstterm>exécuteur</firstterm>.
79      </para>
80
81      <para>
82       Il le fait tout d'abord en créant tous les <firstterm>chemins</firstterm>
83       possibles menant au même résultat. Par exemple, s'il existe un index sur
84       une relation à parcourir, il existe deux chemins pour le parcours. Une
85       possibilité est un simple parcours séquentiel et l'autre possibilité est
86       d'utiliser l'index. Ensuite, le coût pour l'exécution de chaque chemin est
87       estimé et le chemin le moins coûteux est choisi. Ce dernier est étendu en
88       un plan complet que l'exécuteur peut utiliser.
89      </para>
90     </step>
91
92     <step>
93      <para>
94       L'exécuteur passe récursivement dans l'<firstterm>arbre constitué par le
95       plan</firstterm> et retrouve les lignes suivant la façon
96       représentée par le plan. L'exécuteur fait usage du <firstterm>système de
97       stockage</firstterm> lors du parcours des relations, exécute les
98       <firstterm>tris</firstterm> et <firstterm>jointures</firstterm>, évalue
99       les <firstterm>qualifications</firstterm> et finalement renvoie les
100       lignes en question.
101      </para>
102     </step>
103    </procedure>
104
105    <para>
106     Dans les sections suivantes, nous allons parler de chacun des éléments
107     discutés ci-dessus avec plus de détails pour permettre une meilleure
108     compréhension des structures de données et de contrôle internes de
109     <productname>PostgreSQL</productname>.
110    </para>
111   </sect1>
112
113   <sect1 id="connect-estab">
114    <title>Moyens pour établir des connexions</title>
115
116    <para>
117     <productname>PostgreSQL</productname> est implémenté suivant un modèle
118     client/serveur pour chaque <quote>processus par utilisateur</>. Dans ce
119     modèle, il existe un <firstterm>processus client</firstterm> connecté à un
120     seul <firstterm>processus serveur</firstterm>. Comme nous ne savons pas par
121     avance combien de connexions seront établies, nous devons utiliser un
122     <firstterm>processus maître</firstterm> qui lancera un processus serveur à
123     chaque fois qu'une connexion sera demandée. Ce processus maître s'appelle
124     <literal>postmaster</literal> et écoute sur le port TCP/IP spécifié les
125     connexions entrantes. À chaque fois qu'une demande pour une connexion est
126     détectée, le processus <literal>postmaster</literal> lance un nouveau
127     processus fils appelé <literal>postgres</literal>. Les tâches du serveur
128     (processus <literal>postgres</literal>) communiquent entre elles en
129     utilisant des <firstterm>sémaphores</firstterm> et de la <firstterm>mémoire
130     partagée</firstterm> pour s'assurer de l'intégrité des données lors d'un
131     accès simultané aux données.
132    </para>
133
134    <para>
135     Le processus client peut être tout programme comprenant le protocole
136     <productname>PostgreSQL</productname> décrit dans le
137     <xref linkend="protocol">. Beaucoup de clients sont basés sur la
138     bibliothèque C <application>libpq</> mais plusieurs implémentations
139     indépendantes du protocole existent, telle que le pilote Java
140     <application>JDBC</>.
141    </para>
142
143    <para>
144     Une fois la connexion établie, le processus client peut envoyer une requête
145     au serveur (<firstterm>backend</firstterm>). La requête est transmise en
146     texte simple, c'est-à-dire qu'aucune analyse n'a besoin d'être réalisée au
147     niveau de l'<firstterm>interface</firstterm> (client). Le serveur analyse
148     la requête, crée un <firstterm>plan d'exécution</firstterm>, exécute le
149     plan et renvoie les lignes trouvées au client par la connexion établie.
150    </para>
151   </sect1>
152
153   <sect1 id="parser-stage">
154    <title>Étape d'analyse</title>
155
156    <para>
157     L'<firstterm>étape d'analyse</firstterm> consiste en deux parties&nbsp;:
158
159     <itemizedlist>
160      <listitem>
161       <para>
162        L'<firstterm>analyseur</firstterm> défini dans
163        <filename>gram.y</filename> et <filename>scan.l</filename> est construit
164        en utilisant les outils Unix <application>yacc</application> et
165        <application>lex</application>.
166       </para>
167      </listitem>
168      <listitem>
169       <para>
170        Le <firstterm>processus de transformation</firstterm> fait des
171        modifications et des ajouts aux structures de données renvoyées par
172        l'analyseur.
173       </para>
174      </listitem>
175     </itemizedlist>
176    </para>
177
178    <sect2>
179     <title>Analyseur</title>
180
181     <para>
182      L'analyseur doit vérifier que la syntaxe de la chaîne de la requête
183      (arrivant comme un texte ASCII) soit valide. Si la syntaxe est correcte, un
184      <firstterm>arbre d'analyse</firstterm> est construit et renvoyé, sinon
185      une erreur est retournée. Les analyseur et vérificateur syntaxiques sont
186      implémentés en utilisant les outils Unix bien connus que sont
187      <application>lex</application> et <application>yacc</application>.
188     </para>
189
190     <para>
191      L'<firstterm>analyseur lexical</firstterm> est défini dans le fichier
192      <filename>scan.l</filename> et est responsable de la reconnaissance des
193      <firstterm>identificateurs</firstterm>, des <firstterm>mots clés
194      SQL</firstterm>, etc. Pour chaque mot clé ou identificateur trouvé, un
195      <firstterm>jeton</firstterm> est généré et renvoyé à l'analyseur.
196     </para>
197
198     <para>
199      L'analyseur est défini dans le fichier <filename>gram.y</filename> et
200      consiste en un ensemble de <firstterm>règles de grammaire</firstterm> et
201      en des <firstterm>actions</firstterm> à exécuter lorsqu'une règle est
202      découverte. Le code des actions (qui est en langage C) est utilisé pour
203      construire l'arbre d'analyse.
204     </para>
205
206     <para>
207      Le fichier <filename>scan.l</filename> est transformé en fichier source C
208      <filename>scan.c</filename> en utilisant le programme
209      <application>lex</application> et <filename>gram.y</filename> est
210      transformé en <filename>gram.c</filename> en utilisant
211      <application>yacc</application>. Après avoir réalisé ces transformations,
212      un compilateur C normal peut être utilisé pour créer l'analyseur. Ne faites
213      jamais de changement aux fichiers C générés car ils seront écrasés la
214      prochaine fois que <application>lex</application> ou
215      <application>yacc</application> seront appelés.
216
217      <note>
218       <para>
219        Les transformations et compilations mentionnées sont normalement
220        réalisées automatiquement en utilisant les
221        <firstterm>makefile</firstterm> distribués avec les sources de
222        <productname>PostgreSQL</productname>.
223       </para>
224      </note>
225     </para>
226
227     <para>
228      Une description détaillée de <application>yacc</application> ou des règles
229      de grammaire données dans <filename>gram.y</filename> serait en dehors du
230      champ de ce document. Il existe de nombreux livres et documentations en
231      relation avec <application>lex</application> et
232      <application>yacc</application>. Vous devez être familier avec
233      <application>yacc</application> avant de commencer à étudier la grammaire
234      donnée dans <filename>gram.y</filename>, sinon vous ne comprendrez rien à
235      ce qui s'y passe.
236     </para>
237
238    </sect2>
239
240    <sect2>
241      <title>Processus de transformation</title>
242
243     <para>
244      L'étape d'analyse crée un arbre d'analyse utilisant seulement les règles
245      fixes de la structure syntaxique de SQL. Il ne fait aucune recherche dans
246      les catalogues système, donc il n'y a aucune possibilité de comprendre
247      la sémantique détaillée des opérations demandées. Après que l'analyseur
248      ait fini, le <firstterm>processus de transformation</firstterm> prend
249      l'arbre résultant de l'analyseur en entrée et réalise l'interprétation
250      sémantique nécessaire pour connaître les tables, fonctions et opérateurs
251      référencés par la requête. La structure de données construite pour
252      représenter cette information est appelé l'<firstterm>arbre de la
253      requête</>.
254     </para>
255
256     <para>
257      La raison de la séparation de l'analyse brute et de l'analyse sémantique
258      est que les recherches des catalogues système peuvent seulement se faire
259      à l'intérieur d'une transaction, et nous ne voulons pas commencer une
260      transaction immédiatement après avoir reçu une requête. L'analyse brute
261      est suffisante pour identifier les commandes de contrôle des transactions
262      (<command>BEGIN</>, <command>ROLLBACK</>, etc) et elles peuvent être
263      correctement exécutées sans plus d'analyse. Une fois que nous savons que
264      nous gérons une vraie requête (telle que <command>SELECT</> ou
265      <command>UPDATE</>), nous pouvons commencer une transaction si nous n'y
266      sommes pas déjà. C'est seulement maintenant que le processus de
267      transformation peut être appelé.
268     </para>
269
270     <para>
271      La plupart du temps, l'arbre d'une requête créé par le processus de
272      transformation a une structure similaire à l'arbre d'analyse brute mais il
273      existe beaucoup de différences dans le détail. Par exemple, un n&oelig;ud
274      <structname>FuncCall</> dans l'arbre d'analyse représente quelque chose qui
275      ressemble syntaxiquement à l'appel d'une fonction. Il peut être transformé
276      soit en n&oelig;ud <structname>FuncExpr</> soit en n&oelig;ud
277      <structname>Aggref</> suivant que le nom référencé est une fonction
278      ordinaire ou une fonction d'agrégat. De même, des informations sur les
279      types de données réels des colonnes et des résultats sont ajoutées à
280      l'arbre de la requête.
281     </para>
282    </sect2>
283   </sect1>
284
285   <sect1 id="rule-system">
286    <title>Système de règles de <productname>PostgreSQL</productname></title>
287
288    <para>
289     <productname>PostgreSQL</productname> supporte un puissant
290     <firstterm>système de règles</firstterm> pour la spécification des
291     <firstterm>vues</firstterm> et des <firstterm>mises à jour de
292     vues</firstterm> ambiguës. À l'origine, le système de règles de
293     <productname>PostgreSQL</productname> consistait en deux implémentations&nbsp;:
294
295     <itemizedlist>
296      <listitem>
297       <para>
298        Le premier a fonctionné en utilisant le <firstterm>niveau des
299        lignes</firstterm> et était implémenté profondément dans
300        l'<firstterm>exécuteur</firstterm>. Le système de règles était appelé
301        à chaque fois qu'il fallait accéder à une ligne individuelle. Cette
302        implémentation a été supprimée en 1995 quand la dernière version
303        officielle du projet <productname>Berkeley Postgres</productname> a été
304        transformé en <productname>Postgres95</productname>.
305       </para>
306      </listitem>
307
308      <listitem>
309       <para>
310        La deuxième implémentation du système de règles est une technique appelée
311        la <firstterm>réécriture de requêtes</firstterm>. Le <firstterm>système
312        de réécriture</firstterm> est un module qui existe entre
313        l'<firstterm>étape d'analyse</firstterm> et le
314        <firstterm>planificateur/optimiseur</firstterm>. Cette technique est
315        toujours implémentée.
316       </para>
317      </listitem>
318     </itemizedlist>
319    </para>
320
321    <para>
322     Le système de réécriture de requêtes est vu plus en détails dans le
323     <xref linkend="rules">, donc il n'est pas nécessaire d'en parler ici.
324     Nous indiquerons seulement qu'à la fois l'entrée et la sortie du système
325     sont des arbres de requêtes, c'est-à-dire qu'il n'y a pas de changement
326     dans la représentation ou le niveau du détail sémantique des arbres. La
327     réécriture peut être imaginée comme une forme d'expansion de macro.
328    </para>
329
330   </sect1>
331
332   <sect1 id="planner-optimizer">
333    <title>Planificateur/Optimiseur</title>
334
335    <para>
336     La tâche du <firstterm>planificateur/optimiseur</firstterm> est de créer un
337     plan d'exécution optimal. En fait, une requête SQL donnée (et donc, l'arbre
338     d'une requête) peut être exécutée de plusieurs façons, chacune arrivant
339     au même résultat. Si ce calcul est possible, l'optimiseur de la requête
340     examinera chacun des plans d'exécution possibles pour finir par
341     sélectionner le plan d'exécution estimé comme étant le plus rapide.
342    </para>
343
344    <note>
345     <para>
346      Dans certaines situations, examiner chaque moyen d'exécuter une requête
347      prendrait beaucoup de temps et de mémoire. En particulier, cela arrive lors
348      de l'exécution de requêtes impliquant un grand nombre de jointures. Pour
349      déterminer un plan de requête raisonnable (et non optimal) dans un temps
350      raisonnable, <productname>PostgreSQL</productname> utilise un
351      <xref linkend="geqo" endterm="geqo-title">.
352     </para>
353    </note>
354
355    <para>
356     La procédure de recherche du planificateur fonctionne en fait avec des
357     structures de données appelés <firstterm>chemins</>, qui sont simplement des
358     représentations minimales de plans contenant seulement l'information
359     nécessaire pour que le planificateur puisse prendre ses décisions. Une fois
360     le chemin le moins coûteux déterminé, un <firstterm>arbre plan</> est
361     construit pour être donné à l'exécuteur. Ceci représente le plan d'exécution
362     désiré avec suffisamment de détails pour que l'exécuteur puisse le lancer.
363     Dans le reste de cette section, nous ignorerons la distinction entre chemins
364     et plans.
365    </para>
366
367    <sect2>
368     <title>Générer les plans possibles</title>
369
370     <para>
371      Le planificateur/optimiseur commence par générer des plans pour parcourir
372      chaque relation (table) invididuelle utilisée dans la requête. Les plans
373      possibles sont déterminés par les index disponibles pour chaque relation.
374      Il est toujours possible de réaliser un parcours séquentiel sur une
375      relation, donc un plan de parcours séquentiel est toujours créé. Supposons
376      qu'un index soit défini sur une relation (par exemple un index B-tree) et
377      qu'une requête contienne le filtre <literal>relation.attribut OPR
378      constante</literal>. Si <literal>relation.attribut</literal> correspond à
379      la clé de l'index B-tree et <literal>OPR</literal> est un des opérateurs
380      listés dans la <firstterm>classe d'opérateurs</> de l'index, un autre plan
381      est créé en utilisant l'index B-tree pour parcourir la relation. S'il
382      existe d'autres index et que les restrictions de la requête font
383      correspondre une clé à un index, d'autres plans seront considérés.
384     </para>
385
386     <para>
387      Une fois que tous les plans probables ont été trouvés pour parcourir les
388      relations simples, des plans pour les relations jointes sont créés. Le
389      planificateur/optimiseur préfère considérer les jointures entre deux
390      relations pour lesquelles il existe une clause de jointure correspondante
391      dans la qualification <literal>WHERE</literal> (c'est-à-dire pour lequel
392      une restriction comme <literal>where rel1.attr1=rel2.attr2</literal>
393      existe). Des paires de jointures sans clause de jointure sont considérées
394      seulement quand il n'existe pas d'autre choix, c'est-à-dire lorsqu'une
395      relation particulière n'a pas de clause de jointure disponible vers toute
396      autre relation. Tous les plans possibles sont générés pour chaque paire de
397      jointure considérée par le planificateur/optimiseur. Les trois stratégies
398      possibles de jointure sont&nbsp;:
399
400      <itemizedlist>
401       <listitem>
402        <para>
403         <firstterm>jointure de boucle imbriquée</firstterm> (NdT&nbsp;: nested
404         loop join)&nbsp;: la relation de droite est parcourue une fois pour
405         chaque ligne trouvée dans la relation de gauche. Cette stratégie est
406         facile à implémenter mais peut être très coûteuse en temps. (Par contre,
407         si la relation de droite peut être parcourue à l'aide d'un index, ceci
408         peut être une bonne stratégie. Il est possible d'utiliser des valeurs
409         provenant de la ligne actuelle de la relation de gauche comme clés pour
410         un parcours indexé à droite.)
411        </para>
412       </listitem>
413
414       <listitem>
415        <para>
416         <firstterm>jointure tri et assemblage</firstterm> (NdT&nbsp;: merge
417         sort join)&nbsp;: Chaque relation est triée sur les attributs de la
418         jointure avant que la jointure ne commence. Puis, les deux relations
419         sont parcourues en parallèle et les lignes correspondantes sont
420         combinées pour former des lignes jointes. Ce type de jointure est plus
421         intéressant parce que chaque relation n'est parcourue qu'une seule fois.
422         Le tri requis pourrait être réalisé soit par une étape explicite de tri
423         soit en parcourant la relation dans le bon ordre en utilisant un index
424         sur la clé de la jointure.
425        </para>
426       </listitem>
427
428       <listitem>
429        <para>
430         <firstterm>jointure de découpage</firstterm> (hash join)&nbsp;: la
431         relation de droite est tout d'abord parcourue et chargée dans une table
432         de découpage en utilisant ses attributs de jointure comme clés de
433         découpage. Ensuite, la relation de gauche est parcourue et les valeurs
434         appropriées de chaque ligne trouvée sont utilisées comme clés de
435         découpage pour localiser les lignes correspondantes dans la table.
436        </para>
437       </listitem>
438      </itemizedlist>
439     </para>
440
441     <para>
442      Quand la requête implique plus de deux relations, le résultat final doit
443      être construit par un arbre d'étapes de jointure, chacune ayant deux
444      entrées. Le planificateur examine les séquences de jointure possibles pour
445      trouver le moins cher.
446     </para>
447
448     <para>
449      L'arbre de plan terminé est composé de parcours séquentiels ou indexés des
450      relations de base, plus les n&oelig;uds des jointures en boucle, jointures
451      tri et rassemblement, et jointures de découpage si nécessaire, plus toutes
452      les étapes auxiliaires nécessaires, tels que les n&oelig;uds de tri ou les
453      n&oelig;uds de calcul des fonctions d'agrégat. La plupart des types de
454      n&oelig;ud de plan ont la capacité supplémentaire de faire une
455      <firstterm>sélection</> (rejetant les lignes qui ne correspondent pas à une
456      condition booléenne spécifiée) et une <firstterm>projection</> (calcul d'un
457      ensemble de colonnes dérivées basé sur des valeurs de colonnes données,
458      c'est-à-dire l'évaluation d'expressions scalaires si nécessaire). Une des
459      responsabilités du planificateur est d'attacher les conditions de
460      sélection à partir de la clause <literal>WHERE</literal> et du calcul des
461      expressions de calculs requises aux n&oelig;uds les plus appropriés de
462      l'arbre de plan.
463     </para>
464    </sect2>
465   </sect1>
466
467   <sect1 id="executor">
468    <title>Exécuteur</title>
469
470    <para>
471     L'<firstterm>exécuteur</firstterm> prend le plan envoyé par le
472     planificateur/optimiseur et l'exécute récursivement pour extraire
473     l'ensemble requis de lignes. Il s'agit principalement d'un mécanisme de
474     pipeline en demande-envoi. Chaque fois qu'un n&oelig;ud du plan est appelé,
475     il doit apporter une ligne supplémentaire ou indiquer qu'il a fini d'envoyer
476     des lignes.
477    </para>
478
479    <para>
480     Pour donner un exemple concret, supposons que le n&oelig;ud supérieur soit
481     un n&oelig;ud <literal>MergeJoin</literal>. Avant de pouvoir faire une
482     fusion, deux lignes doivent être récupérées (une pour chaque sous-plan).
483     L'exécuteur s'appelle donc récursivement pour exécuter les sous-plans (en
484     commençant par le sous-plan attaché à l'<literal>arbre gauche</literal>).
485     Le nouveau n&oelig;ud supérieur (le n&oelig;ud supérieur du sous-plan
486     gauche) est, disons, un n&oelig;ud <literal>Sort</literal> (NdT&nbsp;: Tri)
487     et un appel récursif est une nouvelle fois nécessaire pour obtenir une ligne
488     en entrée. Le n&oelig;ud fils de <literal>Sort</literal> pourrait être un
489     n&oelig;ud <literal>SeqScan</>, représentant la lecture réelle d'une table.
490     L'exécution de ce n&oelig;ud fait que l'exécuteur récupère une ligne à
491     partir de la table et la renvoie au n&oelig;ud appelant. Le n&oelig;ud
492     <literal>Sort</literal> appellera de façon répétée son fils pour obtenir
493     toutes les lignes à trier. Quand l'entrée est terminée (indiqué par le
494     n&oelig;ud fils renvoyant un NULL au lieu d'une ligne), le code de
495     <literal>Sort</literal> est enfin capable de renvoyer sa première ligne en
496     sortie, c'est-à-dire le premier suivant l'ordre de tri. Il conserve les
497     lignes restantes en mémoire de façon à les renvoyer dans le bon ordre en
498     réponse à des demandes ultérieures.
499    </para>
500
501    <para>
502     Le n&oelig;ud <literal>MergeJoin</literal> demande de la même façon la
503     première ligne à partir du sous-plan droit. Ensuite, il compare les deux
504     lignes pour savoir si elles peuvent être jointes&nbsp;; si c'est le cas, il
505     renvoie la ligne de jointure à son appelant. Au prochain appel, ou
506     immédiatement s'il ne peut pas joindre la paire actuelle d'entrées, il
507     avance sur la prochaine ligne d'une des deux tables (suivant le résultat de
508     la comparaison), et vérifie de nouveau la correspondance. Finalement, un
509     sous-plan est terminé et le n&oelig;ud <literal>MergeJoin</literal> renvoie
510     NULL pour indiquer qu'il n'y a plus de lignes jointes à former.
511    </para>
512
513    <para>
514     Les requêtes complexes peuvent nécessiter un grand nombre de niveaux de
515     n&oelig;uds pour les plans, mais l'approche générale est la même&nbsp;:
516     chaque n&oelig;ud est exécuté et renvoie sa prochaine ligne en sortie à
517     chaque fois qu'il est appelé. Chaque n&oelig;ud est responsable aussi de
518     l'application de toute expression de sélection ou de projection qui lui ont
519     été confiées par le planificateur.
520    </para>
521
522    <para>
523     Le mécanisme de l'exécuteur est utilisé pour évaluer les quatre types de
524     requêtes de base en SQL&nbsp;: <command>SELECT</>, <command>INSERT</>,
525     <command>UPDATE</> et <command>DELETE</>. Pour <command>SELECT</>, le code
526     de l'exécuteur de plus haut niveau a seulement besoin d'envoyer chaque ligne
527     retournée par l'arbre plan de la requête vers le client. Pour
528     <command>INSERT</>, chaque ligne renvoyée est insérée dans la table cible
529     spécifiée par le <command>INSERT</>. (Une simple commande
530     <command>INSERT ... VALUES</> crée un arbre plan trivial consistant en un
531     seul n&oelig;ud, <literal>Result</>, calculant une seule ligne de résultat.
532     Mais <command>INSERT ... SELECT</> peut demander la pleine puissance du
533     mécanisme de l'exécuteur.) Pour <command>UPDATE</>, le planificateur
534     s'arrange pour que chaque ligne calculée inclue toutes les valeurs mises à
535     jour des colonnes, plus le <firstterm>TID</> (tuple ID ou l'identifiant de
536     la ligne) de la ligne de la cible originale&nbsp;; l'exécuteur de plus haut
537     niveau utilise cette information pour créer une nouvelle ligne mise à jour
538     et pour marquer la suppression de l'ancienne ligne. Pour <command>DELETE</>,
539     la seule colonne renvoyée par le plan est le TID, et l'exécuteur de plus
540     haut niveau utilise simplement le TID pour visiter chaque ligne cible et la
541     marquer comme supprimée.
542    </para>
543
544   </sect1>
545
546  </chapter>
547
548 <!-- Keep this comment at the end of the file
549 Local variables:
550 mode:sgml
551 sgml-omittag:nil
552 sgml-shorttag:t
553 sgml-minimize-attributes:nil
554 sgml-always-quote-attributes:t
555 sgml-indent-step:1
556 sgml-indent-data:t
557 sgml-parent-document:nil
558 sgml-default-dtd-file:"./reference.ced"
559 sgml-exposed-tags:nil
560 sgml-local-catalogs:("/usr/lib/sgml/catalog")
561 sgml-local-ecat-files:nil
562 End:
563 -->
Note: See TracBrowser for help on using the browser.