forked from gleu/pgdocs_fr
/
geqo.xml
386 lines (344 loc) · 14.5 KB
/
geqo.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
<?xml version="1.0" encoding="UTF-8"?>
<!-- Dernière modification
le $Date$
par $Author$
révision $Revision$ -->
<!-- SAS : 20071220, PG83b4 -->
<chapter id="geqo">
<chapterinfo>
<author>
<firstname>Martin</firstname>
<surname>Utesch</surname>
<affiliation>
<orgname>
University of Mining and Technology
</orgname>
<orgdiv>
Institute of Automatic Control
</orgdiv>
<address>
<city>
Freiberg
</city>
<country>
Germany
</country>
</address>
</affiliation>
</author>
<date>1997-10-02</date>
</chapterinfo>
<title id="geqo-title">Optimiseur génétique de requêtes
(<foreignphrase>Genetic Query Optimizer</foreignphrase>)</title>
<para>
<note>
<title>Auteur</title>
<para>
Écrit par Martin Utesch (<email>utesch@aut.tu-freiberg.de</email>)
de l'Institut de Contrôle Automatique à l'Université des Mines et de
Technologie de Freiberg, Allemagne.
</para>
</note>
</para>
<sect1 id="geqo-intro">
<title>Gérer les requêtes, un problème d'optimisation complexe</title>
<para>
De tous les opérateurs relationnels, le plus difficile à exécuter et à
optimiser est la jointure (<firstterm>join</firstterm>). Le nombre de plans
de requêtes possibles croît exponentiellement avec le nombre de jointures
de la requête. Un effort supplémentaire d'optimisation est nécessité par
le support de différentes <firstterm>méthodes de jointure</firstterm>
(boucles imbriquées, jointures de hachage, jointures de fusion...) pour
exécuter des jointures individuelles et différents
<firstterm>index</firstterm> (B-tree, hash, GiST et GIN...) pour accéder
aux relations.
</para>
<para>
L'optimiseur standard de requêtes pour <productname>PostgreSQL</productname>
réalise une <firstterm>recherche quasi-exhaustive</firstterm> sur
l'ensemble des stratégies alternatives. Cet algorithme,
introduit à l'origine dans la base de données System R d'IBM, produit un ordre
de jointure quasi-optimal mais peut occuper beaucoup de temps et de
mémoire à mesure que le nombre de jointures d'une requête augmente.
L'optimiseur ordinaire de requêtes de <productname>PostgreSQL</productname>
devient donc inapproprié pour les requêtes qui joignent un grand nombre de tables.
</para>
<!-- electrical power grid ? -->
<para>
L'Institut de Contrôle Automatique de l'Université des Mines et de
Technologie basé à Freiberg, Allemagne, a rencontré des difficultés
lorsqu'il s'est agi d'utiliser <productname>PostgreSQL</productname>
comme moteur d'un système d'aide à la décision reposant sur une base de
connaissance utilisé pour la maintenance d'une grille
de courant électrique. Le SGBD devait gérer des requêtes
à nombreuses jointures pour la machine d'inférence de la base de
connaissances. Le nombre de jointures de ces requêtes empêchait
l'utilisation de l'optimiseur de requête standard.
</para>
<!-- Supprimé dans la v83
<para>
Les difficultés en terme de performance pour l'exploration des plans de
requêtes possibles ont créé la demande du développement d'une nouvelle
technique d'optimisation.
</para>
-->
<para>
La suite du document décrit le codage d'un <firstterm>algorithme
génétique</firstterm> de résolution de l'ordonnancement des jointures
qui soit efficace pour les requêtes à jointures nombreuses.
</para>
</sect1>
<sect1 id="geqo-intro2">
<title>Algorithmes génétiques</title>
<!-- fitness : ? Je doute qu'il s'agisse de forme physique :-/
to fit : s'intégrer, entrer, s'encastrer...
adaptation me semble convenir -->
<para>
L'algorithme génétique (<acronym>GA</acronym>) est une méthode
d'optimisation heuristique qui opère par recherches non déterministes,
aléatoires. L'ensemble des solutions possibles au problème d'optimisation
est considéré comme une <firstterm>population</firstterm>
d'<firstterm>individus</firstterm>. Le degré d'adaptation d'un individu
à son environnement est indiqué par sa <firstterm>valeur d'adaptation</firstterm>
(<foreignphrase>fitness</foreignphrase>).
</para>
<para>
Les coordonnées d'un individu dans l'espace de recherche sont représentées
par des <firstterm>chromosomes</firstterm>, en fait un ensemble de chaînes
de caractères. Un <firstterm>gène</firstterm> est une sous-section de
chromosome qui code la valeur d'un paramètre simple en cours d'optimisation.
Les codages habituels d'un gène sont
<firstterm>binary</firstterm> ou <firstterm>integer</firstterm>.
</para>
<para>
La simulation des opérations d'évolution
(<firstterm>recombinaison</firstterm>, <firstterm>mutation</firstterm> et
<firstterm>sélection</firstterm>) permet de trouver de nouvelles
générations de points de recherche qui présentent une meilleure adaptation
moyenne que leurs ancêtres.
</para>
<para>
Selon la <acronym>FAQ</acronym> de <systemitem
class="resource">comp.ai.genetic</systemitem>, on ne peut pas réellement
affirmer qu'un <acronym>GA</acronym> n'est pas purement une recherche
aléatoire. Un <acronym>GA</acronym> utilise des processus stochastiques, mais
le résultat est assurément non-aléatoire (il est mieux qu'aléatoire).
</para>
<figure id="geqo-diagram">
<title>Diagramme structuré d'un algorithme génétique</title>
<informaltable frame="none">
<tgroup cols="2">
<tbody>
<row>
<entry>P(t)</entry>
<entry>génération des ancêtres au temps t</entry>
</row>
<row>
<entry>P''(t)</entry>
<entry>génération des descendants au temps t</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<literallayout class="monospaced">
+=========================================+
|>>>>>>>>>>> Algorithme GA <<<<<<<<<<<<<<|
+=========================================+
| INITIALISE t := 0 |
+=========================================+
| INITIALISE P(t) |
+=========================================+
| évalue ADAPTATION de P(t) |
+=========================================+
| tant que pas CRITERE ARRET faire |
| +-------------------------------------+
| | P'(t) := RECOMBINAISON{P(t)} |
| +-------------------------------------+
| | P''(t) := MUTATION{P'(t)} |
| +-------------------------------------+
| | P(t+1) := SELECTION{P''(t) + P(t)} |
| +-------------------------------------+
| | évalue ADAPTATION de P''(t) |
| +-------------------------------------+
| | t := t + 1 |
+===+=====================================+
</literallayout>
</figure>
</sect1>
<sect1 id="geqo-pg-intro">
<title>Optimisation génétique des requêtes (<acronym>GEQO</acronym>) dans
PostgreSQL</title>
<para>
Le module <acronym>GEQO</acronym> utilise une approche du problème
d'optimisation des requêtes similaire à celui du voyageur
de commerce (<acronym>TSP</acronym>). Les plans de requêtes possibles sont
codés comme des chaînes d'entiers. Chaque chaîne représente l'ordre de
jointure d'une relation de la requête à une autre. Par exemple, l'arbre de
jointure
<literallayout class="monospaced">
/\
/\ 2
/\ 3
4 1
</literallayout>
est codé avec la chaîne d'entiers '4-1-3-2', ce qui signifie :
première jointure entre les relations '4' et '1', puis '3' et enfin
'2', avec 1, 2, 3, 4 les identifiants des relations pour l'optimiseur de
<productname>PostgreSQL</productname>.
</para>
<para>
Les caractéristiques spécifiques de l'implantation du
<acronym>GEQO</acronym> sont :
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<para>
<!-- least fit : plus divergent ? -->
l'utilisation d'un algorithme génétique monostable (ou à état stable)
(remplacement des individus les moins ciblés au lieu d'un remplacement
global de génération) permet une convergence rapide vers des plans de
requêtes améliorés ; c'est indispensable au traitement des requêtes dans un
temps raisonnable ;
</para>
</listitem>
<listitem>
<para>
<!-- Je me souviens maintenant pourquoi j'avais déjà buté sur cette
relecture du temps de la 8.0... -->
<!-- edge recombination crossover et edge losses ? -->
l'utilisation de croisements (recombinaisons) aux limites est particulièrement
adapté pour la restriction des pertes aux limites lors de la résolution
du problème du voyageur de commerce par un algorithme génétique ;
</para>
</listitem>
<listitem>
<para>
la mutation en tant qu'opérateur génétique est rendue obsolète afin
d'éviter la nécessité de mécanismes de réparation lors de la génération
de tournées valides du problème du voyageur de commerce.
</para>
</listitem>
</itemizedlist>
</para>
<para>
Diverses parties du module <acronym>GEQO</acronym> sont adaptées de l'algorithme
Genitor de D. Whitley.
</para>
<para>
Le module <acronym>GEQO</acronym> permet à l'optimiseur de requêtes de
<productname>PostgreSQL</productname> de supporter les requêtes disposant
de jointures importantes de manière efficace via une recherche non
exhaustive.
</para>
<sect2>
<title>Génération par le <acronym>GEQO</acronym> des plans envisageables</title>
<para>
Le processus de planification du <acronym>GEQO</acronym> utilise le code
standard du planificateur pour créer les plans de parcours des relations
individuelles. Les plans de jointure sont alors développés à l'aide de
l'approche génétique. Comme décrit plus bas, chaque plan de jointure
candidat est représenté par une séquence à laquelle joindre les relations
de base. Lors de l'étape initiale, l'algorithme produit simplement quelques
séquences de jointure aléatoirement. Pour chaque séquence considérée, le
code du planificateur standard est invoqué pour estimer le coût de la
requête à l'aide de cette séquence. (Pour chaque étape de la séquence, les
trois stratégies de jointure sont considérées ; et tous les plans de
parcours initiaux sont disponibles. Le coût estimé est le moins coûteux.)
Les séquences dont le coût est moindre sont considérées <quote>plus
adaptée</quote> que celle de coût plus élevé. L'algorithme génétique
élimine les candidats les moins adaptés. De nouveaux candidats sont alors
engendrés par combinaison de gènes de candidats à forte valeur
d'adaptation — par l'utilisation de portions aléatoires de plans
peu coûteux pour créer de nouvelles séquences. Ce processus est répété
jusqu'à ce qu'un nombre prédéterminé de séquences aient été considérées ;
la meilleure séquence rencontrée pendant la recherche est utilisée pour
produire le plan final.
</para>
<para>
Ce processus est intrinsèquement non-déterministe, du fait des choix
aléatoires effectués lors de la sélection initiale de la population et lors des
<quote>mutations</quote> des meilleurs candidats qui s'en suivent. De ce
fait, des plans différents peuvent être choisis d'une exécution à l'autre,
ce qui conduit à des temps d'exécution et des ordres de colonnes
différents.
</para>
</sect2>
<sect2 id="geqo-future">
<title>Tâches à réaliser pour la future implantation du <acronym>GEQO</acronym>
</title>
<para>
Un gros travail est toujours nécessaire pour améliorer les paramètres de
l'algorithme génétique.
Dans le fichier
<filename>src/backend/optimizer/geqo/geqo_main.c</filename>,
pour les routines <function>gimme_pool_size</function> et
<function>gimme_number_generations</function>, il faut trouver un
compromis pour que les paramètres satisfassent deux besoins
concurrents :
<itemizedlist spacing="compact">
<listitem>
<para>
l'optimisation du plan de requête ;
</para>
</listitem>
<listitem>
<para>
le temps de calcul.
</para>
</listitem>
</itemizedlist>
</para>
<para>
Dans l'implantation courante, l'adaptation de chaque séquence de jointure
candidate est estimée par l'exécution ab-initio du code standard de
sélection de jointure et d'estimation de coût utilisé par le planificateur.
Avec l'hypothèse que différents candidats utilisent des sous-séquences de
jointure similaires, une grande partie du travail est répétée. Ce
processus peut être grandement accéléré en retenant les estimations de
coût des sous-jointures. Le problème consiste à éviter d'étendre
inutilement la mémoire en mémorisant ces états.
</para>
<para>
À un niveau plus basique, il n'est pas certain qu'optimiser
une requête avec un algorithme génétique conçu pour le problème du
voyageur de commerce soit approprié. Dans le cas du voyageur de commerce, le
coût associé à une sous-chaîne quelconque (tour partiel) est
indépendant du reste du tour, mais cela n'est certainement plus vrai dans
le cas de l'optimisation de requêtes. Du coup, la question reste posée quant au fait
que la recombinaison soit la procédure de mutation la plus efficace.
</para>
</sect2>
</sect1>
<sect1 id="geqo-biblio">
<title>Lectures supplémentaires</title>
<para>
Les ressources suivantes contiennent des informations supplémentaires sur
les algorithmes génétiques :
<itemizedlist>
<listitem>
<para>
<ulink url="http://www.aip.de/~ast/EvolCompFAQ/">The
Hitch-Hiker's Guide to Evolutionary Computation</ulink> (FAQ de <ulink
url="news://comp.ai.genetic"></ulink>) ;
</para>
</listitem>
<listitem>
<para>
<ulink url="http://www.red3d.com/cwr/evolve.html">Evolutionary
Computation and its application to art and design</ulink>, par
Craig Reynolds ;
</para>
</listitem>
<listitem>
<para>
<xref linkend="elma04"/>
</para>
</listitem>
<listitem>
<para>
<xref linkend="fong"/>
</para>
</listitem>
</itemizedlist>
</para>
</sect1>
</chapter>