From 1264cd520502357cd30c4e9dbfc6727ea35e29b5 Mon Sep 17 00:00:00 2001 From: Vladimir Rachkin <33569237+robozmey@users.noreply.github.com> Date: Mon, 14 Oct 2024 16:26:24 +0300 Subject: [PATCH 01/10] =?UTF-8?q?Rows=20out=20=D0=B2=20EXPLAIN=20ANALYZE?= =?UTF-8?q?=20(#44)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add "Rows out" print in cdbexplain_showExecStats set gp_enable_explain_rows_out=on; explain (analyze,verbose,format text) select * from tt where a > b; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=8) (actual time=2.534..223.679 rows=499500 loops=1) Output: a, b -> Seq Scan on public.tt (cost=0.00..431.00 rows=1 width=8) (actual time=0.145..127.350 rows=166742 loops=1) Output: a, b Filter: (tt.a > tt.b) Rows out: 166500.00 rows avg x 3 workers, 166742 rows max (seg0), 166340 rows min (seg2). ... --- src/backend/cdb/cdbvars.c | 1 + src/backend/commands/explain_gp.c | 60 +++++++++++++++++++ src/backend/utils/misc/guc_gp.c | 11 ++++ src/include/cdb/cdbvars.h | 7 +++ src/include/utils/unsync_guc_name.h | 1 + src/test/regress/expected/gp_explain.out | 16 +++++ .../regress/expected/gp_explain_optimizer.out | 16 +++++ src/test/regress/sql/gp_explain.sql | 5 ++ 8 files changed, 117 insertions(+) diff --git a/src/backend/cdb/cdbvars.c b/src/backend/cdb/cdbvars.c index e759b8b2edd..053a9b1412d 100644 --- a/src/backend/cdb/cdbvars.c +++ b/src/backend/cdb/cdbvars.c @@ -277,6 +277,7 @@ int gp_hashagg_groups_per_bucket = 5; int gp_motion_slice_noop = 0; /* Cloudberry Database Experimental Feature GUCs */ +bool gp_enable_explain_rows_out = false; bool gp_enable_explain_allstat = false; bool gp_enable_motion_deadlock_sanity = false; /* planning time sanity * check */ diff --git a/src/backend/commands/explain_gp.c b/src/backend/commands/explain_gp.c index 7c3fbe46f48..d197322435b 100644 --- a/src/backend/commands/explain_gp.c +++ b/src/backend/commands/explain_gp.c @@ -1703,6 +1703,66 @@ cdbexplain_showExecStats(struct PlanState *planstate, ExplainState *es) } pfree(extraData.data); + /* + * Print "Rows out" + */ + + if (gp_enable_explain_rows_out && es->analyze && ns->ninst > 0) { + double alltuples = 0; + double maxtuples = ns->insts[0].ntuples; + int maxseg = 0; + double mintuples = ns->insts[0].ntuples; + int minseg = 0; + + for (i = 0; i < ns->ninst; i++) + { + CdbExplain_StatInst *nsi = &ns->insts[i]; + + alltuples += nsi->ntuples; + + if (nsi->ntuples > maxtuples) { + maxtuples = nsi->ntuples; + maxseg = ns->segindex0 + i; + } + + if (nsi->ntuples < mintuples) { + mintuples = nsi->ntuples; + minseg = ns->segindex0 + i; + } + } + + double avgtuples = alltuples / ns->ninst; + + if (es->format == EXPLAIN_FORMAT_TEXT) + { + /* + * create a header for all stats: separate each individual stat by an + * underscore, separate the grouped stats for each node by a slash + */ + appendStringInfoSpaces(es->str, es->indent * 2); + appendStringInfoString(es->str, "Rows out: "); + + appendStringInfo(es->str, + "%0.2f rows avg x %d workers, %0.f rows max (seg%d), %0.f rows min (seg%d).\n", + avgtuples, + ns->ninst, + maxtuples, + maxseg, + mintuples, + minseg); + } + else { + // ExplainOpenGroup("Rows Out", NULL, false, es); + ExplainPropertyInteger("Workers", ns->ninst, es); + ExplainPropertyFloat("Average Rows", avgtuples, 1, es); + ExplainPropertyFloat("Max Rows", maxtuples, 0, es); + ExplainPropertyInteger("Max Rows Segment", maxseg, es); + ExplainPropertyFloat("Min Rows", mintuples, 0, es); + ExplainPropertyInteger("Min Rows Segment", minseg, es); + // ExplainCloseGroup("Rows out", NULL, false, es); + } + } + /* * Dump stats for all workers. */ diff --git a/src/backend/utils/misc/guc_gp.c b/src/backend/utils/misc/guc_gp.c index 92775541695..bbe8d3cc901 100644 --- a/src/backend/utils/misc/guc_gp.c +++ b/src/backend/utils/misc/guc_gp.c @@ -772,6 +772,17 @@ struct config_bool ConfigureNamesBool_gp[] = NULL, NULL, NULL }, + { + {"gp_enable_explain_rows_out", PGC_USERSET, CLIENT_CONN_OTHER, + gettext_noop("Experimental feature: print avg, min and max rows out in segments in EXPLAIN ANALYZE."), + NULL, + GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE + }, + &gp_enable_explain_rows_out, + false, + NULL, NULL, NULL + }, + { {"gp_enable_explain_allstat", PGC_USERSET, CLIENT_CONN_OTHER, gettext_noop("Experimental feature: dump stats for all segments in EXPLAIN ANALYZE."), diff --git a/src/include/cdb/cdbvars.h b/src/include/cdb/cdbvars.h index dba9f4c8cf0..f8dae9dccff 100644 --- a/src/include/cdb/cdbvars.h +++ b/src/include/cdb/cdbvars.h @@ -626,6 +626,13 @@ extern bool gp_enable_agg_pushdown; */ extern bool gp_enable_preunique; +/* May Cloudberry print statistics as average, minimum and maximum rows out + * during EXPLAIN ANALYZE? + * + */ + +extern bool gp_enable_explain_rows_out; + /* May Cloudberry dump statistics for all segments as a huge ugly string * during EXPLAIN ANALYZE? * diff --git a/src/include/utils/unsync_guc_name.h b/src/include/utils/unsync_guc_name.h index aa8be6f4ec7..8cb952b63ef 100644 --- a/src/include/utils/unsync_guc_name.h +++ b/src/include/utils/unsync_guc_name.h @@ -178,6 +178,7 @@ "gp_enable_agg_pushdown", "gp_enable_ao_indexscan", "gp_enable_direct_dispatch", + "gp_enable_explain_rows_out", "gp_enable_explain_allstat", "gp_enable_fast_sri", "gp_enable_global_deadlock_detector", diff --git a/src/test/regress/expected/gp_explain.out b/src/test/regress/expected/gp_explain.out index df9364fc5ad..88a6d8f2b91 100644 --- a/src/test/regress/expected/gp_explain.out +++ b/src/test/regress/expected/gp_explain.out @@ -436,6 +436,22 @@ explain analyze SELECT * FROM explaintest; (8 rows) set gp_enable_explain_allstat=DEFAULT; +-- Test explain rows out. +set gp_enable_explain_rows_out=on; +explain analyze SELECT * FROM explaintest; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3.10 rows=10 width=4) (actual time=0.266..0.384 rows=5 loops=2) + -> Seq Scan on explaintest (cost=0.00..3.10 rows=4 width=4) (actual time=0.011..0.013 rows=2 loops=2) + Rows out: 3.33 rows avg x 3 workers, 5 rows max (seg1), 2 rows min (seg2). + (slice0) Executor memory: 322K bytes. + (slice1) Executor memory: 50K bytes avg x 3 workers, 50K bytes max (seg0). + Memory used: 128000kB + Optimizer: Postgres query optimizer + Total runtime: 2.600 ms +(8 rows) + +set gp_enable_explain_rows_out=DEFAULT; -- -- Test GPDB-specific EXPLAIN (SLICETABLE) option. -- diff --git a/src/test/regress/expected/gp_explain_optimizer.out b/src/test/regress/expected/gp_explain_optimizer.out index 4e94d6d3de0..b3c63c32967 100644 --- a/src/test/regress/expected/gp_explain_optimizer.out +++ b/src/test/regress/expected/gp_explain_optimizer.out @@ -458,6 +458,22 @@ explain analyze SELECT * FROM explaintest; (8 rows) set gp_enable_explain_allstat=DEFAULT; +-- Test explain rows out. +set gp_enable_explain_rows_out=on; +explain analyze SELECT * FROM explaintest; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=10 width=4) (actual time=0.298..0.302 rows=5 loops=2) + -> Seq Scan on explaintest (cost=0.00..431.00 rows=4 width=4) (actual time=0.013..0.015 rows=2 loops=2) + Rows out: 3.33 rows avg x 3 workers, 5 rows max (seg1), 2 rows min (seg2). + (slice0) Executor memory: 290K bytes. + (slice1) Executor memory: 50K bytes avg x 3 workers, 50K bytes max (seg0). + Memory used: 128000kB + Optimizer: Pivotal Optimizer (GPORCA) version 3.2.0 + Total runtime: 1.577 ms +(8 rows) + +set gp_enable_explain_rows_out=DEFAULT; -- -- Test GPDB-specific EXPLAIN (SLICETABLE) option. -- diff --git a/src/test/regress/sql/gp_explain.sql b/src/test/regress/sql/gp_explain.sql index ca9bbdb7d69..03c5dc3fdc8 100644 --- a/src/test/regress/sql/gp_explain.sql +++ b/src/test/regress/sql/gp_explain.sql @@ -228,6 +228,11 @@ set gp_enable_explain_allstat=on; explain analyze SELECT * FROM explaintest; set gp_enable_explain_allstat=DEFAULT; +-- Test explain rows out. +set gp_enable_explain_rows_out=on; +explain analyze SELECT * FROM explaintest; +set gp_enable_explain_rows_out=DEFAULT; + -- -- Test GPDB-specific EXPLAIN (SLICETABLE) option. From e1320a92706a9353444accae61f69c67b903876e Mon Sep 17 00:00:00 2001 From: Vladimir Rachkin Date: Tue, 15 Oct 2024 14:47:31 +0300 Subject: [PATCH 02/10] Fix GUC description --- src/backend/utils/misc/guc_gp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/utils/misc/guc_gp.c b/src/backend/utils/misc/guc_gp.c index bbe8d3cc901..7f5c07ae599 100644 --- a/src/backend/utils/misc/guc_gp.c +++ b/src/backend/utils/misc/guc_gp.c @@ -774,7 +774,7 @@ struct config_bool ConfigureNamesBool_gp[] = { {"gp_enable_explain_rows_out", PGC_USERSET, CLIENT_CONN_OTHER, - gettext_noop("Experimental feature: print avg, min and max rows out in segments in EXPLAIN ANALYZE."), + gettext_noop("GP5 feature: print avg, min and max rows out in segments in EXPLAIN ANALYZE."), NULL, GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE }, From ecca72cbe197809112cf3f6b25c359fc01750d78 Mon Sep 17 00:00:00 2001 From: Vladimir Rachkin Date: Thu, 24 Oct 2024 16:05:02 +0300 Subject: [PATCH 03/10] Use CdbExplain_NodeSummary to get max and avg --- src/backend/commands/explain_gp.c | 88 ++++++++++++------------------- 1 file changed, 35 insertions(+), 53 deletions(-) diff --git a/src/backend/commands/explain_gp.c b/src/backend/commands/explain_gp.c index f6c961eb7c0..86f1bc0a399 100644 --- a/src/backend/commands/explain_gp.c +++ b/src/backend/commands/explain_gp.c @@ -1721,60 +1721,42 @@ cdbexplain_showExecStats(struct PlanState *planstate, ExplainState *es) */ if (gp_enable_explain_rows_out && es->analyze && ns->ninst > 0) { - double alltuples = 0; - double maxtuples = ns->insts[0].ntuples; - int maxseg = 0; - double mintuples = ns->insts[0].ntuples; - int minseg = 0; + double ntuples_max = ns->ntuples.vmax; + int ntuples_imax = ns->ntuples.imax; + double ntuples_min = ns->ntuples.vmax; /// TODO + int ntuples_imin = ns->ntuples.imax; /// TODO + double ntuples_avg = ns->ntuples.vsum / ns->ntuples.vcnt; + int ntuples_cnt = ns->ntuples.vcnt; - for (i = 0; i < ns->ninst; i++) - { - CdbExplain_StatInst *nsi = &ns->insts[i]; - - alltuples += nsi->ntuples; - - if (nsi->ntuples > maxtuples) { - maxtuples = nsi->ntuples; - maxseg = ns->segindex0 + i; - } - - if (nsi->ntuples < mintuples) { - mintuples = nsi->ntuples; - minseg = ns->segindex0 + i; - } - } - - double avgtuples = alltuples / ns->ninst; - - if (es->format == EXPLAIN_FORMAT_TEXT) - { - /* - * create a header for all stats: separate each individual stat by an - * underscore, separate the grouped stats for each node by a slash - */ - appendStringInfoSpaces(es->str, es->indent * 2); - appendStringInfoString(es->str, "Rows out: "); - - appendStringInfo(es->str, - "%0.2f rows avg x %d workers, %0.f rows max (seg%d), %0.f rows min (seg%d).\n", - avgtuples, - ns->ninst, - maxtuples, - maxseg, - mintuples, - minseg); - } - else { - // ExplainOpenGroup("Rows Out", NULL, false, es); - ExplainPropertyInteger("Workers", ns->ninst, es); - ExplainPropertyFloat("Average Rows", avgtuples, 1, es); - ExplainPropertyFloat("Max Rows", maxtuples, 0, es); - ExplainPropertyInteger("Max Rows Segment", maxseg, es); - ExplainPropertyFloat("Min Rows", mintuples, 0, es); - ExplainPropertyInteger("Min Rows Segment", minseg, es); - // ExplainCloseGroup("Rows out", NULL, false, es); - } - } + if (es->format == EXPLAIN_FORMAT_TEXT) + { + /* + * create a header for all stats: separate each individual stat by an + * underscore, separate the grouped stats for each node by a slash + */ + appendStringInfoSpaces(es->str, es->indent * 2); + appendStringInfoString(es->str, "Rows out: "); + + appendStringInfo(es->str, + "%.2f rows avg x %d workers, %.0f rows max (seg%d), %.0f rows min (seg%d).\n", + ntuples_avg, + ntuples_cnt, + ntuples_max, + ntuples_imax, + ntuples_min, + ntuples_imin); + } + else { + // ExplainOpenGroup("Rows Out", NULL, false, es); + ExplainPropertyInteger("Workers", NULL, ntuples_cnt, es); + ExplainPropertyFloat("Average Rows", NULL, ntuples_avg, 1, es); + ExplainPropertyFloat("Max Rows", NULL, ntuples_max, 0, es); + ExplainPropertyInteger("Max Rows Segment", NULL, ntuples_imax, es); + ExplainPropertyFloat("Min Rows", NULL, ntuples_min, 0, es); + ExplainPropertyInteger("Min Rows Segment", NULL, ntuples_imin, es); + // ExplainCloseGroup("Rows out", NULL, false, es); + } + } /* * Dump stats for all workers. From cbff7f0878b985fabacbc88d99f259b69883f00b Mon Sep 17 00:00:00 2001 From: Vladimir Rachkin Date: Thu, 24 Oct 2024 16:13:48 +0300 Subject: [PATCH 04/10] Add min to CdbExplain_Agg --- src/backend/commands/explain_gp.c | 6 +++--- src/include/cdb/cdbexplain.h | 11 +++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/backend/commands/explain_gp.c b/src/backend/commands/explain_gp.c index 86f1bc0a399..d6ce0f112b5 100644 --- a/src/backend/commands/explain_gp.c +++ b/src/backend/commands/explain_gp.c @@ -1723,9 +1723,9 @@ cdbexplain_showExecStats(struct PlanState *planstate, ExplainState *es) if (gp_enable_explain_rows_out && es->analyze && ns->ninst > 0) { double ntuples_max = ns->ntuples.vmax; int ntuples_imax = ns->ntuples.imax; - double ntuples_min = ns->ntuples.vmax; /// TODO - int ntuples_imin = ns->ntuples.imax; /// TODO - double ntuples_avg = ns->ntuples.vsum / ns->ntuples.vcnt; + double ntuples_min = ns->ntuples.vmin; + int ntuples_imin = ns->ntuples.imin; + double ntuples_avg = cdbexplain_agg_avg(&ns->ntuples); int ntuples_cnt = ns->ntuples.vcnt; if (es->format == EXPLAIN_FORMAT_TEXT) diff --git a/src/include/cdb/cdbexplain.h b/src/include/cdb/cdbexplain.h index 67fd98de3bf..a63436f063d 100644 --- a/src/include/cdb/cdbexplain.h +++ b/src/include/cdb/cdbexplain.h @@ -26,18 +26,22 @@ struct CdbExplain_ShowStatCtx; /* private, in "cdb/cdbexplain.c" */ typedef struct { double vmax; /* maximum value of statistic */ + double vmin; /* minimum value of statistic */ double vsum; /* sum of values */ int vcnt; /* count of values > 0 */ int imax; /* id of 1st observation having maximum value */ + int imin; /* id of 1st observation having minimum value */ } CdbExplain_Agg; static inline void cdbexplain_agg_init0(CdbExplain_Agg *agg) { agg->vmax = 0; + agg->vmin = 0; agg->vsum = 0; agg->vcnt = 0; agg->imax = 0; + agg->imin = 0; } static inline bool @@ -48,6 +52,13 @@ cdbexplain_agg_upd(CdbExplain_Agg *agg, double v, int id) agg->vsum += v; agg->vcnt++; + if (v < agg->vmin || + agg->vcnt == 1) + { + agg->vmin = v; + agg->imin = id; + } + if (v > agg->vmax || agg->vcnt == 1) { From c0448fe0b44e26db2ede9b74dae1691168172213 Mon Sep 17 00:00:00 2001 From: Vladimir Rachkin Date: Thu, 24 Oct 2024 16:37:20 +0300 Subject: [PATCH 05/10] Add min to CdbExplain_DepStatAcc --- src/backend/commands/explain_gp.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/backend/commands/explain_gp.c b/src/backend/commands/explain_gp.c index d6ce0f112b5..dcdd9c13fab 100644 --- a/src/backend/commands/explain_gp.c +++ b/src/backend/commands/explain_gp.c @@ -941,7 +941,7 @@ cdbexplain_collectStatsFromNode(PlanState *planstate, CdbExplain_SendStatCtx *ct */ typedef struct CdbExplain_DepStatAcc { - /* vmax, vsum, vcnt, segmax */ + /* vmax, vmin, vsum, vcnt, segmax, segmin */ CdbExplain_Agg agg; /* max's received StatHdr */ CdbExplain_StatHdr *rshmax; @@ -949,6 +949,12 @@ typedef struct CdbExplain_DepStatAcc CdbExplain_StatInst *rsimax; /* max's inst in NodeSummary */ CdbExplain_StatInst *nsimax; + /* min's received StatHdr */ + CdbExplain_StatHdr *rshmin; + /* min's received inst in StatHdr */ + CdbExplain_StatInst *rsimin; + /* min's inst in NodeSummary */ + CdbExplain_StatInst *nsimin; /* max run-time of all the segments */ double max_total; /* start time of the first iteration for node with maximum runtime */ @@ -962,6 +968,9 @@ cdbexplain_depStatAcc_init0(CdbExplain_DepStatAcc *acc) acc->rshmax = NULL; acc->rsimax = NULL; acc->nsimax = NULL; + acc->rshmin = NULL; + acc->rsimin = NULL; + acc->nsimin = NULL; acc->max_total = 0; INSTR_TIME_SET_ZERO(acc->firststart_of_max_total); } /* cdbexplain_depStatAcc_init0 */ @@ -979,6 +988,11 @@ cdbexplain_depStatAcc_upd(CdbExplain_DepStatAcc *acc, acc->rsimax = rsi; acc->nsimax = nsi; } + if (rsh->segindex == acc->agg.imin) { + acc->rshmin = rsh; + acc->rsimin = rsi; + acc->nsimin = nsi; + } if (acc->max_total < nsi->total) { acc->max_total = nsi->total; From 490521ec01ff7c1859defd4907fa1386a63baf56 Mon Sep 17 00:00:00 2001 From: Vladimir Rachkin Date: Fri, 25 Oct 2024 14:05:30 +0300 Subject: [PATCH 06/10] Remove rshmin, rsimin, nsimin from CdbExplain_DepStatAcc --- src/backend/commands/explain_gp.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/backend/commands/explain_gp.c b/src/backend/commands/explain_gp.c index dcdd9c13fab..0905eb56555 100644 --- a/src/backend/commands/explain_gp.c +++ b/src/backend/commands/explain_gp.c @@ -949,12 +949,6 @@ typedef struct CdbExplain_DepStatAcc CdbExplain_StatInst *rsimax; /* max's inst in NodeSummary */ CdbExplain_StatInst *nsimax; - /* min's received StatHdr */ - CdbExplain_StatHdr *rshmin; - /* min's received inst in StatHdr */ - CdbExplain_StatInst *rsimin; - /* min's inst in NodeSummary */ - CdbExplain_StatInst *nsimin; /* max run-time of all the segments */ double max_total; /* start time of the first iteration for node with maximum runtime */ @@ -968,9 +962,6 @@ cdbexplain_depStatAcc_init0(CdbExplain_DepStatAcc *acc) acc->rshmax = NULL; acc->rsimax = NULL; acc->nsimax = NULL; - acc->rshmin = NULL; - acc->rsimin = NULL; - acc->nsimin = NULL; acc->max_total = 0; INSTR_TIME_SET_ZERO(acc->firststart_of_max_total); } /* cdbexplain_depStatAcc_init0 */ @@ -988,11 +979,6 @@ cdbexplain_depStatAcc_upd(CdbExplain_DepStatAcc *acc, acc->rsimax = rsi; acc->nsimax = nsi; } - if (rsh->segindex == acc->agg.imin) { - acc->rshmin = rsh; - acc->rsimin = rsi; - acc->nsimin = nsi; - } if (acc->max_total < nsi->total) { acc->max_total = nsi->total; From 0b7ab049c59eca39cd375bf59c32bf5d46ddf323 Mon Sep 17 00:00:00 2001 From: Vladimir Rachkin Date: Thu, 31 Oct 2024 12:57:25 +0300 Subject: [PATCH 07/10] Change GUC gp_enable_explain_rows_out description --- src/backend/utils/misc/guc_gp.c | 2 +- src/include/cdb/cdbvars.h | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/backend/utils/misc/guc_gp.c b/src/backend/utils/misc/guc_gp.c index 75c03f29ac4..d90901aec07 100644 --- a/src/backend/utils/misc/guc_gp.c +++ b/src/backend/utils/misc/guc_gp.c @@ -777,7 +777,7 @@ struct config_bool ConfigureNamesBool_gp[] = { {"gp_enable_explain_rows_out", PGC_USERSET, CLIENT_CONN_OTHER, - gettext_noop("GP5 feature: print avg, min and max rows out in segments in EXPLAIN ANALYZE."), + gettext_noop("Print avg, min and max rows out and which segments reach them in EXPLAIN ANALYZE."), NULL, GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE }, diff --git a/src/include/cdb/cdbvars.h b/src/include/cdb/cdbvars.h index 6dfc8283343..73ee06bead2 100644 --- a/src/include/cdb/cdbvars.h +++ b/src/include/cdb/cdbvars.h @@ -631,10 +631,9 @@ extern bool gp_enable_agg_pushdown; extern bool gp_enable_preunique; /* May Cloudberry print statistics as average, minimum and maximum rows out - * during EXPLAIN ANALYZE? + * and on which segments reach them for each node during EXPLAIN ANALYZE? * */ - extern bool gp_enable_explain_rows_out; /* May Cloudberry dump statistics for all segments as a huge ugly string From d6aa761bb17c1ca8b9a4a6d13285bee38a490a4b Mon Sep 17 00:00:00 2001 From: Vladimir Rachkin Date: Mon, 11 Nov 2024 12:07:50 +0300 Subject: [PATCH 08/10] Remove unused code --- src/backend/commands/explain_gp.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/backend/commands/explain_gp.c b/src/backend/commands/explain_gp.c index 0905eb56555..50e443b42d5 100644 --- a/src/backend/commands/explain_gp.c +++ b/src/backend/commands/explain_gp.c @@ -1747,14 +1747,12 @@ cdbexplain_showExecStats(struct PlanState *planstate, ExplainState *es) ntuples_imin); } else { - // ExplainOpenGroup("Rows Out", NULL, false, es); ExplainPropertyInteger("Workers", NULL, ntuples_cnt, es); ExplainPropertyFloat("Average Rows", NULL, ntuples_avg, 1, es); ExplainPropertyFloat("Max Rows", NULL, ntuples_max, 0, es); ExplainPropertyInteger("Max Rows Segment", NULL, ntuples_imax, es); ExplainPropertyFloat("Min Rows", NULL, ntuples_min, 0, es); ExplainPropertyInteger("Min Rows Segment", NULL, ntuples_imin, es); - // ExplainCloseGroup("Rows out", NULL, false, es); } } From 07a73a38d3ae31cfc74a0b4c1beffb5f4df2a555 Mon Sep 17 00:00:00 2001 From: Vladimir Rachkin Date: Thu, 21 Nov 2024 11:11:01 +0300 Subject: [PATCH 09/10] Fix test --- src/test/regress/expected/gp_explain.out | 16 ++++++---------- .../regress/expected/gp_explain_optimizer.out | 16 ++++++---------- src/test/regress/sql/gp_explain.sql | 2 +- 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/src/test/regress/expected/gp_explain.out b/src/test/regress/expected/gp_explain.out index 1f0625d8bd0..b1844b0cf70 100644 --- a/src/test/regress/expected/gp_explain.out +++ b/src/test/regress/expected/gp_explain.out @@ -438,18 +438,14 @@ explain analyze SELECT * FROM explaintest; set gp_enable_explain_allstat=DEFAULT; -- Test explain rows out. set gp_enable_explain_rows_out=on; -explain analyze SELECT * FROM explaintest; +explain (costs off, summary off, timing off, analyze) SELECT * FROM explaintest; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3.10 rows=10 width=4) (actual time=0.266..0.384 rows=5 loops=2) - -> Seq Scan on explaintest (cost=0.00..3.10 rows=4 width=4) (actual time=0.011..0.013 rows=2 loops=2) - Rows out: 3.33 rows avg x 3 workers, 5 rows max (seg1), 2 rows min (seg2). - (slice0) Executor memory: 322K bytes. - (slice1) Executor memory: 50K bytes avg x 3 workers, 50K bytes max (seg0). - Memory used: 128000kB - Optimizer: Postgres query optimizer - Total runtime: 2.600 ms -(8 rows) + Gather Motion 3:1 (slice1; segments: 3) (actual rows=10 loops=1) + Rows out: 10.00 rows avg x 1 workers, 10 rows max (seg-1), 10 rows min (seg-1). + -> Seq Scan on explaintest (actual rows=5 loops=1) + Rows out: 3.33 rows avg x 3 workers, 5 rows max (seg0), 1 rows min (seg1). +(5 rows) set gp_enable_explain_rows_out=DEFAULT; -- diff --git a/src/test/regress/expected/gp_explain_optimizer.out b/src/test/regress/expected/gp_explain_optimizer.out index 3e9858ede98..ce3696fbd86 100644 --- a/src/test/regress/expected/gp_explain_optimizer.out +++ b/src/test/regress/expected/gp_explain_optimizer.out @@ -460,18 +460,14 @@ explain analyze SELECT * FROM explaintest; set gp_enable_explain_allstat=DEFAULT; -- Test explain rows out. set gp_enable_explain_rows_out=on; -explain analyze SELECT * FROM explaintest; +explain (costs off, summary off, timing off, analyze) SELECT * FROM explaintest; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=10 width=4) (actual time=0.298..0.302 rows=5 loops=2) - -> Seq Scan on explaintest (cost=0.00..431.00 rows=4 width=4) (actual time=0.013..0.015 rows=2 loops=2) - Rows out: 3.33 rows avg x 3 workers, 5 rows max (seg1), 2 rows min (seg2). - (slice0) Executor memory: 290K bytes. - (slice1) Executor memory: 50K bytes avg x 3 workers, 50K bytes max (seg0). - Memory used: 128000kB - Optimizer: Pivotal Optimizer (GPORCA) version 3.2.0 - Total runtime: 1.577 ms -(8 rows) + Gather Motion 3:1 (slice1; segments: 3) (actual rows=10 loops=1) + Rows out: 10.00 rows avg x 1 workers, 10 rows max (seg-1), 10 rows min (seg-1). + -> Seq Scan on explaintest (actual rows=5 loops=1) + Rows out: 3.33 rows avg x 3 workers, 5 rows max (seg0), 1 rows min (seg1). +(5 rows) set gp_enable_explain_rows_out=DEFAULT; -- diff --git a/src/test/regress/sql/gp_explain.sql b/src/test/regress/sql/gp_explain.sql index 03c5dc3fdc8..d358a9616f9 100644 --- a/src/test/regress/sql/gp_explain.sql +++ b/src/test/regress/sql/gp_explain.sql @@ -230,7 +230,7 @@ set gp_enable_explain_allstat=DEFAULT; -- Test explain rows out. set gp_enable_explain_rows_out=on; -explain analyze SELECT * FROM explaintest; +explain (costs off, summary off, timing off, analyze) SELECT * FROM explaintest; set gp_enable_explain_rows_out=DEFAULT; From d0193b8dde5b0a4aba3dc3bd0e0ab5ffe0eb5792 Mon Sep 17 00:00:00 2001 From: Vladimir Rachkin Date: Thu, 21 Nov 2024 12:04:14 +0300 Subject: [PATCH 10/10] Expand test for rows out --- src/test/regress/expected/gp_explain.out | 42 ++++++++++++++----- .../regress/expected/gp_explain_optimizer.out | 42 ++++++++++++++----- src/test/regress/sql/gp_explain.sql | 11 +++-- 3 files changed, 72 insertions(+), 23 deletions(-) diff --git a/src/test/regress/expected/gp_explain.out b/src/test/regress/expected/gp_explain.out index b1844b0cf70..caa72c15e9b 100644 --- a/src/test/regress/expected/gp_explain.out +++ b/src/test/regress/expected/gp_explain.out @@ -437,17 +437,39 @@ explain analyze SELECT * FROM explaintest; set gp_enable_explain_allstat=DEFAULT; -- Test explain rows out. -set gp_enable_explain_rows_out=on; -explain (costs off, summary off, timing off, analyze) SELECT * FROM explaintest; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (actual rows=10 loops=1) - Rows out: 10.00 rows avg x 1 workers, 10 rows max (seg-1), 10 rows min (seg-1). - -> Seq Scan on explaintest (actual rows=5 loops=1) - Rows out: 3.33 rows avg x 3 workers, 5 rows max (seg0), 1 rows min (seg1). -(5 rows) +begin; +set local gp_enable_explain_rows_out=on; +create table tt (a int, b int); +explain(costs off, summary off, timing off, analyze) +insert into tt select * from generate_series(1,1000)a,generate_series(1,1000)b; +QUERY PLAN +___________ + Insert on tt (actual rows=0 loops=1) + Rows out: 0.00 rows avg x 0 workers, 0 rows max (seg0), 0 rows min (seg0). + -> Result (actual rows=340000 loops=1) + Rows out: 333333.33 rows avg x 3 workers, 340000 rows max (seg2), 322000 rows min (seg1). + -> Result (actual rows=340000 loops=1) + Rows out: 333333.33 rows avg x 3 workers, 340000 rows max (seg2), 322000 rows min (seg1). + -> Nested Loop (actual rows=1000000 loops=1) + Join Filter: true + Rows out: 1000000.00 rows avg x 3 workers, 1000000 rows max (seg0), 1000000 rows min (seg0). + -> Function Scan on generate_series generate_series_1 (actual rows=1000 loops=1) + Rows out: 1000.00 rows avg x 3 workers, 1000 rows max (seg0), 1000 rows min (seg0). + -> Function Scan on generate_series (actual rows=999 loops=1001) + Rows out: 1000001.00 rows avg x 3 workers, 1000001 rows max (seg0), 1000001 rows min (seg0). + +explain(costs off, summary off, timing off, analyze) +select * from tt where a > b; +QUERY PLAN +___________ + Gather Motion 3:1 (slice1; segments: 3) (actual rows=499500 loops=1) + Rows out: 499500.00 rows avg x 1 workers, 499500 rows max (seg-1), 499500 rows min (seg-1). + -> Seq Scan on tt (actual rows=172218 loops=1) + Filter: (a > b) + Rows Removed by Filter: 167782 + Rows out: 166500.00 rows avg x 3 workers, 172218 rows max (seg2), 160958 rows min (seg1). -set gp_enable_explain_rows_out=DEFAULT; +abort; -- -- Test GPDB-specific EXPLAIN (SLICETABLE) option. -- diff --git a/src/test/regress/expected/gp_explain_optimizer.out b/src/test/regress/expected/gp_explain_optimizer.out index ce3696fbd86..0e8e4aef6aa 100644 --- a/src/test/regress/expected/gp_explain_optimizer.out +++ b/src/test/regress/expected/gp_explain_optimizer.out @@ -459,17 +459,39 @@ explain analyze SELECT * FROM explaintest; set gp_enable_explain_allstat=DEFAULT; -- Test explain rows out. -set gp_enable_explain_rows_out=on; -explain (costs off, summary off, timing off, analyze) SELECT * FROM explaintest; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (actual rows=10 loops=1) - Rows out: 10.00 rows avg x 1 workers, 10 rows max (seg-1), 10 rows min (seg-1). - -> Seq Scan on explaintest (actual rows=5 loops=1) - Rows out: 3.33 rows avg x 3 workers, 5 rows max (seg0), 1 rows min (seg1). -(5 rows) +begin; +set local gp_enable_explain_rows_out=on; +create table tt (a int, b int); +explain(costs off, summary off, timing off, analyze) +insert into tt select * from generate_series(1,1000)a,generate_series(1,1000)b; +QUERY PLAN +___________ + Insert on tt (actual rows=0 loops=1) + Rows out: 0.00 rows avg x 0 workers, 0 rows max (seg0), 0 rows min (seg0). + -> Result (actual rows=340000 loops=1) + Rows out: 333333.33 rows avg x 3 workers, 340000 rows max (seg2), 322000 rows min (seg1). + -> Result (actual rows=340000 loops=1) + Rows out: 333333.33 rows avg x 3 workers, 340000 rows max (seg2), 322000 rows min (seg1). + -> Nested Loop (actual rows=1000000 loops=1) + Join Filter: true + Rows out: 1000000.00 rows avg x 3 workers, 1000000 rows max (seg0), 1000000 rows min (seg0). + -> Function Scan on generate_series generate_series_1 (actual rows=1000 loops=1) + Rows out: 1000.00 rows avg x 3 workers, 1000 rows max (seg0), 1000 rows min (seg0). + -> Function Scan on generate_series (actual rows=999 loops=1001) + Rows out: 1000001.00 rows avg x 3 workers, 1000001 rows max (seg0), 1000001 rows min (seg0). + +explain(costs off, summary off, timing off, analyze) +select * from tt where a > b; +QUERY PLAN +___________ + Gather Motion 3:1 (slice1; segments: 3) (actual rows=499500 loops=1) + Rows out: 499500.00 rows avg x 1 workers, 499500 rows max (seg-1), 499500 rows min (seg-1). + -> Seq Scan on tt (actual rows=172218 loops=1) + Filter: (a > b) + Rows Removed by Filter: 167782 + Rows out: 166500.00 rows avg x 3 workers, 172218 rows max (seg2), 160958 rows min (seg1). -set gp_enable_explain_rows_out=DEFAULT; +abort; -- -- Test GPDB-specific EXPLAIN (SLICETABLE) option. -- diff --git a/src/test/regress/sql/gp_explain.sql b/src/test/regress/sql/gp_explain.sql index d358a9616f9..302123cae06 100644 --- a/src/test/regress/sql/gp_explain.sql +++ b/src/test/regress/sql/gp_explain.sql @@ -229,9 +229,14 @@ explain analyze SELECT * FROM explaintest; set gp_enable_explain_allstat=DEFAULT; -- Test explain rows out. -set gp_enable_explain_rows_out=on; -explain (costs off, summary off, timing off, analyze) SELECT * FROM explaintest; -set gp_enable_explain_rows_out=DEFAULT; +begin; +set local gp_enable_explain_rows_out=on; +create table tt (a int, b int); +explain(costs off, summary off, timing off, analyze) +insert into tt select * from generate_series(1,1000)a,generate_series(1,1000)b; +explain(costs off, summary off, timing off, analyze) +select * from tt where a > b; +abort; --