Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd54c6b6

Browse files
committed
Improve some dirty code about calculation of a node rows production.
Fix the problem with full plan state tree passing.Improve AQO messaging system.
1 parentf75482f commitd54c6b6

File tree

3 files changed

+83
-57
lines changed

3 files changed

+83
-57
lines changed

‎aqo_pg12.patch‎

Lines changed: 53 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
2-
index 92969636b7..42446d4e93 100644
2+
index 92969636b7..d05b07e037 100644
33
--- a/src/backend/commands/explain.c
44
+++ b/src/backend/commands/explain.c
5-
@@ -46,6 +46,9 @@ ExplainOneQuery_hook_type ExplainOneQuery_hook = NULL;
5+
@@ -24,6 +24,7 @@
6+
#include "nodes/extensible.h"
7+
#include "nodes/makefuncs.h"
8+
#include "nodes/nodeFuncs.h"
9+
+#include "optimizer/cost.h"
10+
#include "parser/parsetree.h"
11+
#include "rewrite/rewriteHandler.h"
12+
#include "storage/bufmgr.h"
13+
@@ -46,6 +47,9 @@ ExplainOneQuery_hook_type ExplainOneQuery_hook = NULL;
614
/* Hook for plugins to get control in explain_get_index_name() */
715
explain_get_index_name_hook_type explain_get_index_name_hook = NULL;
816

@@ -12,7 +20,7 @@ index 92969636b7..42446d4e93 100644
1220

1321
/* OR-able flags for ExplainXMLTag() */
1422
#define X_OPENING 0
15-
@@ -596,6 +599,10 @@ ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into, ExplainState *es,
23+
@@ -596,6 +600,10 @@ ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into, ExplainState *es,
1624
ExplainPropertyFloat("Execution Time", "ms", 1000.0 * totaltime, 3,
1725
es);
1826

@@ -22,45 +30,41 @@ index 92969636b7..42446d4e93 100644
2230
+
2331
ExplainCloseGroup("Query", NULL, true, es);
2432
}
25-
26-
@@ -1041,6 +1048,17 @@ ExplainPreScanNode(PlanState *planstate, Bitmapset **rels_used)
27-
return planstate_tree_walker(planstate, ExplainPreScanNode, rels_used);
28-
}
29-
30-
+static bool
31-
+we_need_to_sum_tuples(const Plan *plan)
32-
+{
33-
+if (plan->path_parallel_workers > 0 && (
34-
+plan->parallel_aware || nodeTag(plan) == T_HashJoin ||
35-
+nodeTag(plan) == T_MergeJoin ||
36-
+nodeTag(plan) == T_NestLoop))
37-
+return true;
38-
+return false;
39-
+}
40-
+
41-
/*
42-
* ExplainNode -
43-
* Appends a description of a plan tree to es->str
44-
@@ -1523,6 +1541,24 @@ ExplainNode(PlanState *planstate, List *ancestors,
33+
34+
@@ -1523,6 +1531,38 @@ ExplainNode(PlanState *planstate, List *ancestors,
4535
appendStringInfo(es->str,
4636
" (actual rows=%.0f loops=%.0f)",
4737
rows, nloops);
38+
+
4839
+#ifdef AQO_EXPLAIN
49-
+if (es->verbose && plan)
40+
+if (es->verbose && plan && planstate->instrument)
5041
+{
5142
+int wrkrs = 1;
5243
+double error = -1.;
5344
+
54-
+if (planstate->worker_instrument && we_need_to_sum_tuples(plan))
55-
+wrkrs += planstate->worker_instrument->num_workers;
45+
+if (planstate->worker_instrument && IsParallelTuplesProcessing(plan))
46+
+{
47+
+int i;
48+
+for (i = 0; i < planstate->worker_instrument->num_workers; i++)
49+
+{
50+
+Instrumentation *instrument = &planstate->worker_instrument->instrument[i];
51+
+if (instrument->nloops <= 0)
52+
+continue;
53+
+wrkrs++;
54+
+}
55+
+}
5656
+
5757
+if (plan->predicted_cardinality > 0.)
5858
+{
59-
+error = 100. * (plan->predicted_cardinality-(rows*wrkrs)) / (rows * wrkrs);
59+
+error = 100. * (plan->predicted_cardinality - (rows*wrkrs))
60+
+/ plan->predicted_cardinality;
6061
+appendStringInfo(es->str,
61-
+" (AQO predicted: cardinality=%.0lf, error=%.0lf%%,fss=%d)",
62+
+" (AQO predicted: cardinality=%lf, error=%.0lf%%,fsspace_hash=%d)",
6263
+plan->predicted_cardinality, error, plan->fss_hash);
6364
+}
65+
+else
66+
+appendStringInfo(es->str, " (AQO not used, fsspace_hash=%d)",
67+
+plan->fss_hash);
6468
+}
6569
+#endif
6670
}
@@ -84,7 +88,7 @@ index 78deade89b..b1470147e9 100644
8488
COPY_BITMAPSET_FIELD(allParam);
8589
}
8690
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
87-
index a2a9b1f7be..bc7a69bb05 100644
91+
index a2a9b1f7be..4b766b9885 100644
8892
--- a/src/backend/optimizer/path/costsize.c
8993
+++ b/src/backend/optimizer/path/costsize.c
9094
@@ -96,6 +96,10 @@
@@ -401,7 +405,22 @@ index a2a9b1f7be..bc7a69bb05 100644
401405
{
402406
doublenrows;
403407

404-
@@ -5478,10 +5594,10 @@ page_size(double tuples, int width)
408+
@@ -5474,14 +5590,25 @@ page_size(double tuples, int width)
409+
return ceil(relation_byte_size(tuples, width) / BLCKSZ);
410+
}
411+
412+
+bool
413+
+IsParallelTuplesProcessing(const Plan *plan)
414+
+{
415+
+if (plan->path_parallel_workers > 0 && (
416+
+plan->parallel_aware || nodeTag(plan) == T_HashJoin ||
417+
+nodeTag(plan) == T_MergeJoin ||
418+
+nodeTag(plan) == T_NestLoop))
419+
+return true;
420+
+return false;
421+
+}
422+
+
423+
/*
405424
* Estimate the fraction of the work that each worker will do given the
406425
* number of workers budgeted for the path.
407426
*/
@@ -415,7 +434,7 @@ index a2a9b1f7be..bc7a69bb05 100644
415434

416435
/*
417436
* Early experience with parallel query suggests that when there is only
418-
@@ -5498,7 +5614,7 @@ get_parallel_divisor(Path *path)
437+
@@ -5498,7 +5625,7 @@ get_parallel_divisor(Path *path)
419438
{
420439
doubleleader_contribution;
421440

@@ -927,7 +946,7 @@ index 70f8b8e22b..d188c2596a 100644
927946
* Information for management of parameter-change-driven rescanning
928947
*
929948
diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h
930-
index 9b6bdbc518..4f93e222ca 100644
949+
index 9b6bdbc518..2a0caa6474 100644
931950
--- a/src/include/optimizer/cost.h
932951
+++ b/src/include/optimizer/cost.h
933952
@@ -39,6 +39,33 @@ typedef enum
@@ -998,10 +1017,11 @@ index 9b6bdbc518..4f93e222ca 100644
9981017
extern void set_subquery_size_estimates(PlannerInfo *root, RelOptInfo *rel);
9991018
extern void set_function_size_estimates(PlannerInfo *root, RelOptInfo *rel);
10001019
extern void set_values_size_estimates(PlannerInfo *root, RelOptInfo *rel);
1001-
@@ -198,5 +241,6 @@ extern void set_foreign_size_estimates(PlannerInfo *root, RelOptInfo *rel);
1020+
@@ -198,5 +241,7 @@ extern void set_foreign_size_estimates(PlannerInfo *root, RelOptInfo *rel);
10021021
extern PathTarget *set_pathtarget_cost_width(PlannerInfo *root, PathTarget *target);
10031022
extern double compute_bitmap_pages(PlannerInfo *root, RelOptInfo *baserel,
10041023
Path *bitmapqual, int loop_count, Cost *cost, double *tuple);
1024+
+extern bool IsParallelTuplesProcessing(const Plan *plan);
10051025
+extern double get_parallel_divisor(int parallel_workers);
10061026

10071027
#endif/* COST_H */

‎cardinality_estimation.c‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include"aqo.h"
2+
#include"optimizer/optimizer.h"
23

34
/*****************************************************************************
45
*
@@ -53,5 +54,5 @@ predict_for_relation(List *restrict_clauses, List *selectivities, List *relids,
5354
if (result<0)
5455
return-1;
5556
else
56-
returnexp(result);
57+
returnclamp_row_est(exp(result));
5758
}

‎postprocessing.c‎

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include"aqo.h"
22
#include"access/parallel.h"
3+
#include"optimizer/optimizer.h"
34
#include"utils/queryenvironment.h"
45

56
/*****************************************************************************
@@ -184,17 +185,6 @@ restore_selectivities(List *clauselist,
184185
returnlst;
185186
}
186187

187-
staticbool
188-
we_need_to_sum_tuples(constPlan*plan)
189-
{
190-
if (plan->path_parallel_workers>0&& (
191-
plan->parallel_aware||nodeTag(plan)==T_HashJoin||
192-
nodeTag(plan)==T_MergeJoin||
193-
nodeTag(plan)==T_NestLoop))
194-
return true;
195-
return false;
196-
}
197-
198188
/*
199189
* Walks over obtained PlanState tree, collects relation objects with their
200190
* clauses, selectivities and relids and passes each object to learn_sample.
@@ -210,8 +200,9 @@ static bool
210200
learnOnPlanState(PlanState*p,void*context)
211201
{
212202
aqo_obj_stat*ctx= (aqo_obj_stat*)context;
203+
aqo_obj_statSubplanCtx= {NIL,NIL,NIL};
213204

214-
planstate_tree_walker(p,learnOnPlanState,context);
205+
planstate_tree_walker(p,learnOnPlanState,(void*)&SubplanCtx);
215206

216207
/*
217208
* Some nodes inserts after planning step (See T_Hash node type).
@@ -225,9 +216,11 @@ learnOnPlanState(PlanState *p, void *context)
225216
p->plan->path_relids,
226217
p->plan->path_jointype,
227218
p->plan->was_parametrized);
228-
ctx->selectivities=list_concat(ctx->selectivities,cur_selectivities);
229-
ctx->clauselist=list_concat(ctx->clauselist,
219+
SubplanCtx.selectivities=list_concat(SubplanCtx.selectivities,
220+
cur_selectivities);
221+
SubplanCtx.clauselist=list_concat(SubplanCtx.clauselist,
230222
list_copy(p->plan->path_clauses));
223+
231224
if (p->plan->path_relids!=NIL)
232225
/*
233226
* This plan can be stored as cached plan. In the case we will have
@@ -246,7 +239,7 @@ learnOnPlanState(PlanState *p, void *context)
246239
if (p->instrument->nloops>0.)
247240
{
248241
/* If we can strongly calculate produced rows, do it. */
249-
if (p->worker_instrument&&we_need_to_sum_tuples(p->plan))
242+
if (p->worker_instrument&&IsParallelTuplesProcessing(p->plan))
250243
{
251244
doublewnloops=0.;
252245
doublewntuples=0.;
@@ -256,6 +249,10 @@ learnOnPlanState(PlanState *p, void *context)
256249
{
257250
doublet=p->worker_instrument->instrument[i].ntuples;
258251
doublel=p->worker_instrument->instrument[i].nloops;
252+
253+
if (l <=0)
254+
continue;
255+
259256
wntuples+=t;
260257
wnloops+=l;
261258
learn_rows+=t/l;
@@ -268,7 +265,8 @@ learnOnPlanState(PlanState *p, void *context)
268265
(p->instrument->nloops-wnloops);
269266
}
270267
else
271-
/* We don't have any workers. */
268+
/* This node does not required to sum tuples of each worker
269+
* to calculate produced rows. */
272270
learn_rows=p->instrument->ntuples /p->instrument->nloops;
273271

274272
if (p->plan->predicted_cardinality>0.)
@@ -283,8 +281,7 @@ learnOnPlanState(PlanState *p, void *context)
283281
predicted=p->plan->plan_rows;
284282

285283
/* It is needed for correct exp(result) calculation. */
286-
if (learn_rows<1.)
287-
learn_rows=1.;
284+
learn_rows=clamp_row_est(learn_rows);
288285
}
289286
else
290287
{
@@ -297,15 +294,20 @@ learnOnPlanState(PlanState *p, void *context)
297294
}
298295

299296
/*
300-
* Some execution logic optimizations can lead to the situation
301-
* than a subtree will never be visited.
297+
* A subtree was not visited. In this case we can not teach AQO
298+
* because ntuples value is equal to 0 and we will got learn rows == 1.
299+
* It is false teaching, because at another place of a plan
300+
* scanning of the node may produce many tuples.
302301
*/
303-
if (!(p->instrument->ntuples <=0.&&p->instrument->nloops<=0.))
304-
learn_sample(ctx->clauselist,ctx->selectivities,
305-
ctx->relidslist,learn_rows,predicted);
302+
if (p->instrument->nloops>=1)
303+
learn_sample(SubplanCtx.clauselist,SubplanCtx.selectivities,
304+
p->plan->path_relids,learn_rows,predicted);
306305
}
307306
}
308307

308+
ctx->clauselist=list_concat(ctx->clauselist,SubplanCtx.clauselist);
309+
ctx->selectivities=list_concat(ctx->selectivities,
310+
SubplanCtx.selectivities);
309311
return false;
310312
}
311313

@@ -429,6 +431,9 @@ aqo_ExecutorEnd(QueryDesc *queryDesc)
429431
cardinality_num_objects=0;
430432

431433
learnOnPlanState(queryDesc->planstate, (void*)&ctx);
434+
list_free(ctx.clauselist);
435+
list_free(ctx.relidslist);
436+
list_free(ctx.selectivities);
432437
}
433438

434439
if (query_context.collect_stat)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp