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

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