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

New cost model for planning, incorporating a penalty for random page

accesses versus sequential accesses, a (very crude) estimate of the
effects of caching on random page accesses, and cost to evaluate WHERE-
clause expressions.  Export critical parameters for this model as SET
variables.  Also, create SET variables for the planner's enable flags
(enable_seqscan, enable_indexscan, etc) so that these can be controlled
more conveniently than via PGOPTIONS.

Planner now estimates both startup cost (cost before retrieving
first tuple) and total cost of each path, so it can optimize queries
with LIMIT on a reasonable basis by interpolating between these costs.
Same facility is a win for EXISTS(...) subqueries and some other cases.

Redesign pathkey representation to achieve a major speedup in planning
(I saw as much as 5X on a 10-way join); also minor changes in planner
to reduce memory consumption by recycling discarded Path nodes and
not constructing unnecessary lists.

Minor cleanups to display more-plausible costs in some cases in
EXPLAIN output.

Initdb forced by change in interface to index cost estimation
functions.
This commit is contained in:
Tom Lane
2000-02-15 20:49:31 +00:00
parent 553b5da6a1
commit b1577a7c78
50 changed files with 3200 additions and 1723 deletions

View File

@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: cost.h,v 1.29 2000/02/07 04:41:04 tgl Exp $
* $Id: cost.h,v 1.30 2000/02/15 20:49:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,9 +17,12 @@
#include "nodes/relation.h"
/* defaults for costsize.c's Cost parameters */
/* NB: cost-estimation code should use the variables, not the constants! */
#define CPU_PAGE_WEIGHT 0.033
#define CPU_INDEX_PAGE_WEIGHT 0.017
/* NB: cost-estimation code should use the variables, not these constants! */
#define DEFAULT_EFFECTIVE_CACHE_SIZE 1000.0 /* measured in pages */
#define DEFAULT_RANDOM_PAGE_COST 4.0
#define DEFAULT_CPU_TUPLE_COST 0.01
#define DEFAULT_CPU_INDEX_TUPLE_COST 0.001
#define DEFAULT_CPU_OPERATOR_COST 0.0025
/* defaults for function attributes used for expensive function calculations */
#define BYTE_PCT 100
@@ -33,8 +36,12 @@
* routines to compute costs and sizes
*/
extern Cost cpu_page_weight;
extern Cost cpu_index_page_weight;
/* parameter variables and flags */
extern double effective_cache_size;
extern Cost random_page_cost;
extern Cost cpu_tuple_cost;
extern Cost cpu_index_tuple_cost;
extern Cost cpu_operator_cost;
extern Cost disable_cost;
extern bool enable_seqscan;
extern bool enable_indexscan;
@@ -44,17 +51,20 @@ extern bool enable_nestloop;
extern bool enable_mergejoin;
extern bool enable_hashjoin;
extern Cost cost_seqscan(RelOptInfo *baserel);
extern Cost cost_index(Query *root, RelOptInfo *baserel, IndexOptInfo *index,
extern void cost_seqscan(Path *path, RelOptInfo *baserel);
extern void cost_index(Path *path, Query *root,
RelOptInfo *baserel, IndexOptInfo *index,
List *indexQuals, bool is_injoin);
extern Cost cost_tidscan(RelOptInfo *baserel, List *tideval);
extern Cost cost_sort(List *pathkeys, double tuples, int width);
extern Cost cost_nestloop(Path *outer_path, Path *inner_path,
bool is_indexjoin);
extern Cost cost_mergejoin(Path *outer_path, Path *inner_path,
extern void cost_tidscan(Path *path, RelOptInfo *baserel, List *tideval);
extern void cost_sort(Path *path, List *pathkeys, double tuples, int width);
extern void cost_nestloop(Path *path, Path *outer_path, Path *inner_path,
List *restrictlist, bool is_indexjoin);
extern void cost_mergejoin(Path *path, Path *outer_path, Path *inner_path,
List *restrictlist,
List *outersortkeys, List *innersortkeys);
extern Cost cost_hashjoin(Path *outer_path, Path *inner_path,
Selectivity innerdisbursion);
extern void cost_hashjoin(Path *path, Path *outer_path, Path *inner_path,
List *restrictlist, Selectivity innerdisbursion);
extern Cost cost_qual_eval(List *quals);
extern void set_baserel_size_estimates(Query *root, RelOptInfo *rel);
extern void set_joinrel_size_estimates(Query *root, RelOptInfo *rel,
RelOptInfo *outer_rel,

View File

@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pathnode.h,v 1.25 2000/02/07 04:41:04 tgl Exp $
* $Id: pathnode.h,v 1.26 2000/02/15 20:49:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,15 +19,18 @@
/*
* prototypes for pathnode.c
*/
extern bool path_is_cheaper(Path *path1, Path *path2);
extern Path *set_cheapest(RelOptInfo *parent_rel, List *pathlist);
extern int compare_path_costs(Path *path1, Path *path2,
CostSelector criterion);
extern int compare_fractional_path_costs(Path *path1, Path *path2,
double fraction);
extern void set_cheapest(RelOptInfo *parent_rel);
extern void add_path(RelOptInfo *parent_rel, Path *new_path);
extern void add_pathlist(RelOptInfo *parent_rel, List *new_paths);
extern Path *create_seqscan_path(RelOptInfo *rel);
extern IndexPath *create_index_path(Query *root, RelOptInfo *rel,
IndexOptInfo *index,
List *restriction_clauses);
List *restriction_clauses,
ScanDirection indexscandir);
extern TidPath *create_tidscan_path(RelOptInfo *rel, List *tideval);
extern NestPath *create_nestloop_path(RelOptInfo *joinrel,

View File

@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: paths.h,v 1.42 2000/02/07 04:41:04 tgl Exp $
* $Id: paths.h,v 1.43 2000/02/15 20:49:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -33,9 +33,9 @@ extern RelOptInfo *make_one_rel(Query *root);
* indxpath.c
* routines to generate index paths
*/
extern List *create_index_paths(Query *root, RelOptInfo *rel, List *indices,
List *restrictinfo_list,
List *joininfo_list);
extern void create_index_paths(Query *root, RelOptInfo *rel, List *indices,
List *restrictinfo_list,
List *joininfo_list);
extern Oid indexable_operator(Expr *clause, Oid opclass, Oid relam,
bool indexkey_on_left);
extern List *extract_or_indexqual_conditions(RelOptInfo *rel,
@@ -47,14 +47,14 @@ extern List *expand_indexqual_conditions(List *indexquals);
* orindxpath.c
* additional routines for indexable OR clauses
*/
extern List *create_or_index_paths(Query *root, RelOptInfo *rel,
List *clauses);
extern void create_or_index_paths(Query *root, RelOptInfo *rel,
List *clauses);
/*
* tidpath.h
* routines to generate tid paths
*/
extern List *create_tidscan_paths(Query *root, RelOptInfo *rel);
extern void create_tidscan_paths(Query *root, RelOptInfo *rel);
/*
* joinpath.c
@@ -89,20 +89,27 @@ typedef enum
PATHKEYS_DIFFERENT /* neither pathkey includes the other */
} PathKeysComparison;
extern void add_equijoined_keys(Query *root, RestrictInfo *restrictinfo);
extern List *canonicalize_pathkeys(Query *root, List *pathkeys);
extern PathKeysComparison compare_pathkeys(List *keys1, List *keys2);
extern bool pathkeys_contained_in(List *keys1, List *keys2);
extern Path *get_cheapest_path_for_pathkeys(List *paths, List *pathkeys,
bool indexpaths_only);
CostSelector cost_criterion);
extern Path *get_cheapest_fractional_path_for_pathkeys(List *paths,
List *pathkeys,
double fraction);
extern List *build_index_pathkeys(Query *root, RelOptInfo *rel,
IndexOptInfo *index);
IndexOptInfo *index,
ScanDirection scandir);
extern List *build_join_pathkeys(List *outer_pathkeys,
List *join_rel_tlist, List *joinclauses);
extern bool commute_pathkeys(List *pathkeys);
List *join_rel_tlist,
List *equi_key_list);
extern List *make_pathkeys_for_sortclauses(List *sortclauses,
List *tlist);
extern List *find_mergeclauses_for_pathkeys(List *pathkeys,
List *restrictinfos);
extern List *make_pathkeys_for_mergeclauses(List *mergeclauses,
extern List *make_pathkeys_for_mergeclauses(Query *root,
List *mergeclauses,
List *tlist);
#endif /* PATHS_H */

View File

@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: planmain.h,v 1.37 2000/01/27 18:11:45 tgl Exp $
* $Id: planmain.h,v 1.38 2000/02/15 20:49:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,7 +20,8 @@
/*
* prototypes for plan/planmain.c
*/
extern Plan *query_planner(Query *root, List *tlist, List *qual);
extern Plan *query_planner(Query *root, List *tlist, List *qual,
double tuple_fraction);
/*
* prototypes for plan/createplan.c
@@ -29,7 +30,7 @@ extern Plan *create_plan(Query *root, Path *best_path);
extern SeqScan *make_seqscan(List *qptlist, List *qpqual, Index scanrelid);
extern Sort *make_sort(List *tlist, Oid nonameid, Plan *lefttree,
int keycount);
extern Agg *make_agg(List *tlist, Plan *lefttree);
extern Agg *make_agg(List *tlist, List *qual, Plan *lefttree);
extern Group *make_group(List *tlist, bool tuplePerGroup, int ngrp,
AttrNumber *grpColIdx, Plan *lefttree);
extern Noname *make_noname(List *tlist, List *pathkeys, Plan *subplan);

View File

@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: planner.h,v 1.13 2000/01/26 05:58:21 momjian Exp $
* $Id: planner.h,v 1.14 2000/02/15 20:49:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,7 +21,7 @@
#include "nodes/plannodes.h"
extern Plan *planner(Query *parse);
extern Plan *union_planner(Query *parse);
extern Plan *union_planner(Query *parse, double tuple_fraction);
extern void pg_checkretval(Oid rettype, List *querytree_list);
#endif /* PLANNER_H */