1
0
mirror of https://github.com/postgres/postgres.git synced 2025-10-27 00:12:01 +03:00

Make GEQO's planning deterministic by having it start from a predictable

random number seed each time.  This is how it used to work years ago, but
we got rid of the seed reset because it was resetting the main random()
sequence and thus having undesirable effects on the rest of the system.
To fix, establish a private random number state for each execution of
geqo(), and initialize the state using the new GUC variable geqo_seed.
People who want to experiment with different random searches can do so
by changing geqo_seed, but you'll always get the same plan for the same
value of geqo_seed (if holding all other planner inputs constant, of course).

The new state is kept in PlannerInfo by adding a "void *" field reserved
for use by join_search hooks.  Most of the rather bulky code changes in
this commit are just arranging to pass PlannerInfo around to all the GEQO
functions (many of which formerly didn't receive it).

Andres Freund, with some editorialization by Tom
This commit is contained in:
Tom Lane
2009-07-16 20:55:44 +00:00
parent c43feefa80
commit f5bc74192d
27 changed files with 305 additions and 202 deletions

View File

@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/optimizer/geqo.h,v 1.44 2009/01/01 17:24:00 momjian Exp $
* $PostgreSQL: pgsql/src/include/optimizer/geqo.h,v 1.45 2009/07/16 20:55:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -46,7 +46,7 @@
/*
* Configuration options
*
* If you change these, update backend/utils/misc/postgresql.sample.conf
* If you change these, update backend/utils/misc/postgresql.conf.sample
*/
extern int Geqo_effort; /* 1 .. 10, knob for adjustment of defaults */
@@ -64,16 +64,17 @@ extern double Geqo_selection_bias;
#define MIN_GEQO_SELECTION_BIAS 1.5
#define MAX_GEQO_SELECTION_BIAS 2.0
extern double Geqo_seed; /* 0 .. 1 */
/*
* Data structure to encapsulate information needed for building plan trees
* (i.e., geqo_eval and gimme_tree).
* Private state for a GEQO run --- accessible via root->join_search_private
*/
typedef struct
{
PlannerInfo *root; /* the query we are planning */
List *initial_rels; /* the base relations */
} GeqoEvalData;
List *initial_rels; /* the base relations we are joining */
unsigned short random_state[3]; /* state for erand48() */
} GeqoPrivateData;
/* routines in geqo_main.c */
@@ -81,8 +82,7 @@ extern RelOptInfo *geqo(PlannerInfo *root,
int number_of_rels, List *initial_rels);
/* routines in geqo_eval.c */
extern Cost geqo_eval(Gene *tour, int num_gene, GeqoEvalData *evaldata);
extern RelOptInfo *gimme_tree(Gene *tour, int num_gene,
GeqoEvalData *evaldata);
extern Cost geqo_eval(PlannerInfo *root, Gene *tour, int num_gene);
extern RelOptInfo *gimme_tree(PlannerInfo *root, Gene *tour, int num_gene);
#endif /* GEQO_H */

View File

@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/optimizer/geqo_copy.h,v 1.21 2009/01/01 17:24:00 momjian Exp $
* $PostgreSQL: pgsql/src/include/optimizer/geqo_copy.h,v 1.22 2009/07/16 20:55:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -22,8 +22,9 @@
#ifndef GEQO_COPY_H
#define GEQO_COPY_H
#include "optimizer/geqo_gene.h"
#include "optimizer/geqo.h"
extern void geqo_copy(Chromosome *chromo1, Chromosome *chromo2, int string_length);
extern void geqo_copy(PlannerInfo *root, Chromosome *chromo1, Chromosome *chromo2, int string_length);
#endif /* GEQO_COPY_H */

View File

@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/optimizer/geqo_mutation.h,v 1.21 2009/01/01 17:24:00 momjian Exp $
* $PostgreSQL: pgsql/src/include/optimizer/geqo_mutation.h,v 1.22 2009/07/16 20:55:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -22,8 +22,9 @@
#ifndef GEQO_MUTATION_H
#define GEQO_MUTATION_H
#include "optimizer/geqo_gene.h"
#include "optimizer/geqo.h"
extern void geqo_mutation(Gene *tour, int num_gene);
extern void geqo_mutation(PlannerInfo *root, Gene *tour, int num_gene);
#endif /* GEQO_MUTATION_H */

View File

@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/optimizer/geqo_pool.h,v 1.25 2009/01/01 17:24:00 momjian Exp $
* $PostgreSQL: pgsql/src/include/optimizer/geqo_pool.h,v 1.26 2009/07/16 20:55:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -26,15 +26,15 @@
#include "optimizer/geqo.h"
extern Pool *alloc_pool(int pool_size, int string_length);
extern void free_pool(Pool *pool);
extern Pool *alloc_pool(PlannerInfo *root, int pool_size, int string_length);
extern void free_pool(PlannerInfo *root, Pool *pool);
extern void random_init_pool(Pool *pool, GeqoEvalData *evaldata);
extern Chromosome *alloc_chromo(int string_length);
extern void free_chromo(Chromosome *chromo);
extern void random_init_pool(PlannerInfo *root, Pool *pool);
extern Chromosome *alloc_chromo(PlannerInfo *root, int string_length);
extern void free_chromo(PlannerInfo *root, Chromosome *chromo);
extern void spread_chromo(Chromosome *chromo, Pool *pool);
extern void spread_chromo(PlannerInfo *root, Chromosome *chromo, Pool *pool);
extern void sort_pool(Pool *pool);
extern void sort_pool(PlannerInfo *root, Pool *pool);
#endif /* GEQO_POOL_H */

View File

@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/optimizer/geqo_random.h,v 1.21 2009/01/01 17:24:00 momjian Exp $
* $PostgreSQL: pgsql/src/include/optimizer/geqo_random.h,v 1.22 2009/07/16 20:55:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -26,13 +26,16 @@
#include <math.h>
/* geqo_rand returns a random float value between 0 and 1 inclusive */
#include "optimizer/geqo.h"
#define geqo_rand() ((double) random() / (double) MAX_RANDOM_VALUE)
extern void geqo_set_seed(PlannerInfo *root, double seed);
/* geqo_rand returns a random float value between 0 and 1 inclusive */
extern double geqo_rand(PlannerInfo *root);
/* geqo_randint returns integer value between lower and upper inclusive */
#define geqo_randint(upper,lower) \
( (int) floor( geqo_rand()*(((upper)-(lower))+0.999999) ) + (lower) )
#define geqo_randint(root, upper, lower) \
( (int) floor( geqo_rand(root)*(((upper)-(lower))+0.999999) ) + (lower) )
#endif /* GEQO_RANDOM_H */

View File

@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/optimizer/geqo_recombination.h,v 1.20 2009/01/01 17:24:00 momjian Exp $
* $PostgreSQL: pgsql/src/include/optimizer/geqo_recombination.h,v 1.21 2009/07/16 20:55:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -24,9 +24,10 @@
#ifndef GEQO_RECOMBINATION_H
#define GEQO_RECOMBINATION_H
#include "optimizer/geqo_gene.h"
#include "optimizer/geqo.h"
extern void init_tour(Gene *tour, int num_gene);
extern void init_tour(PlannerInfo *root, Gene *tour, int num_gene);
/* edge recombination crossover [ERX] */
@@ -38,12 +39,14 @@ typedef struct Edge
int unused_edges;
} Edge;
extern Edge *alloc_edge_table(int num_gene);
extern void free_edge_table(Edge *edge_table);
extern Edge *alloc_edge_table(PlannerInfo *root, int num_gene);
extern void free_edge_table(PlannerInfo *root, Edge *edge_table);
extern float gimme_edge_table(Gene *tour1, Gene *tour2, int num_gene, Edge *edge_table);
extern float gimme_edge_table(PlannerInfo *root, Gene *tour1, Gene *tour2,
int num_gene, Edge *edge_table);
extern int gimme_tour(Edge *edge_table, Gene *new_gene, int num_gene);
extern int gimme_tour(PlannerInfo *root, Edge *edge_table, Gene *new_gene,
int num_gene);
/* partially matched crossover [PMX] */
@@ -51,7 +54,9 @@ extern int gimme_tour(Edge *edge_table, Gene *new_gene, int num_gene);
#define DAD 1 /* indicator for gene from dad */
#define MOM 0 /* indicator for gene from mom */
extern void pmx(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene);
extern void pmx(PlannerInfo *root,
Gene *tour1, Gene *tour2,
Gene *offspring, int num_gene);
typedef struct City
@@ -62,19 +67,23 @@ typedef struct City
int select_list;
} City;
extern City *alloc_city_table(int num_gene);
extern void free_city_table(City *city_table);
extern City *alloc_city_table(PlannerInfo *root, int num_gene);
extern void free_city_table(PlannerInfo *root, City *city_table);
/* cycle crossover [CX] */
extern int cx(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table);
extern int cx(PlannerInfo *root, Gene *tour1, Gene *tour2,
Gene *offspring, int num_gene, City *city_table);
/* position crossover [PX] */
extern void px(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table);
extern void px(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring,
int num_gene, City *city_table);
/* order crossover [OX1] according to Davis */
extern void ox1(Gene *mom, Gene *dad, Gene *offspring, int num_gene, City *city_table);
extern void ox1(PlannerInfo *root, Gene *mom, Gene *dad, Gene *offspring,
int num_gene, City *city_table);
/* order crossover [OX2] according to Syswerda */
extern void ox2(Gene *mom, Gene *dad, Gene *offspring, int num_gene, City *city_table);
extern void ox2(PlannerInfo *root, Gene *mom, Gene *dad, Gene *offspring,
int num_gene, City *city_table);
#endif /* GEQO_RECOMBINATION_H */

View File

@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/optimizer/geqo_selection.h,v 1.21 2009/01/01 17:24:00 momjian Exp $
* $PostgreSQL: pgsql/src/include/optimizer/geqo_selection.h,v 1.22 2009/07/16 20:55:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,8 +23,11 @@
#ifndef GEQO_SELECTION_H
#define GEQO_SELECTION_H
#include "optimizer/geqo_gene.h"
#include "optimizer/geqo.h"
extern void geqo_selection(Chromosome *momma, Chromosome *daddy, Pool *pool, double bias);
extern void geqo_selection(PlannerInfo *root,
Chromosome *momma, Chromosome *daddy,
Pool *pool, double bias);
#endif /* GEQO_SELECTION_H */