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:
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user