Re: Is it useful to record whether plans are generic or custom?

2021-04-05 Thread torikoshia

On 2021-03-26 17:46, Fujii Masao wrote:

On 2021/03/26 0:33, torikoshia wrote:

On 2021-03-25 22:14, Fujii Masao wrote:

On 2021/03/23 16:32, torikoshia wrote:

On 2021-03-05 17:47, Fujii Masao wrote:

Thanks for your comments!


Thanks for updating the patch!

PostgreSQL Patch Tester reported that the patched version failed to 
be compiled

at Windows. Could you fix this issue?
https://ci.appveyor.com/project/postgresql-cfbot/postgresql/build/1.0.131238



It seems PGDLLIMPORT was necessary..
Attached a new one.


Thanks for updating the patch!

In my test, generic_calls for a utility command was not incremented
before PL/pgSQL function was executed. Maybe this is expected behavior.
But it was incremented after the function was executed. Is this a bug?
Please see the following example.


Thanks for reviewing!

It's a bug and regrettably it seems difficult to fix it during this
commitfest.

Marked the patch as "Withdrawn".


Regards,




Re: Is it useful to record whether plans are generic or custom?

2021-03-26 Thread Fujii Masao




On 2021/03/26 0:33, torikoshia wrote:

On 2021-03-25 22:14, Fujii Masao wrote:

On 2021/03/23 16:32, torikoshia wrote:

On 2021-03-05 17:47, Fujii Masao wrote:

Thanks for your comments!


Thanks for updating the patch!

PostgreSQL Patch Tester reported that the patched version failed to be compiled
at Windows. Could you fix this issue?
https://ci.appveyor.com/project/postgresql-cfbot/postgresql/build/1.0.131238



It seems PGDLLIMPORT was necessary..
Attached a new one.


Thanks for updating the patch!

In my test, generic_calls for a utility command was not incremented
before PL/pgSQL function was executed. Maybe this is expected behavior.
But it was incremented after the function was executed. Is this a bug?
Please see the following example.

---
SELECT pg_stat_statements_reset();
SET enable_seqscan TO on;
SELECT calls, generic_calls, query FROM pg_stat_statements WHERE query LIKE 
'%seqscan%';
CREATE OR REPLACE FUNCTION do_ckpt() RETURNS VOID AS $$
BEGIN
  EXECUTE 'CHECKPOINT';
END $$ LANGUAGE plpgsql;
SET enable_seqscan TO on;
SET enable_seqscan TO on;

-- SET commands were executed three times before do_ckpt() was called.
-- generic_calls for SET command is zero in this case.
SELECT calls, generic_calls, query FROM pg_stat_statements WHERE query LIKE 
'%seqscan%';

SELECT do_ckpt();
SET enable_seqscan TO on;
SET enable_seqscan TO on;
SET enable_seqscan TO on;

-- SET commands were executed additionally three times after do_ckpt() was 
called.
-- generic_calls for SET command is three in this case.
SELECT calls, generic_calls, query FROM pg_stat_statements WHERE query LIKE 
'%seqscan%';
---

Regards,

--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION




Re: Is it useful to record whether plans are generic or custom?

2021-03-25 Thread torikoshia

On 2021-03-25 22:14, Fujii Masao wrote:

On 2021/03/23 16:32, torikoshia wrote:

On 2021-03-05 17:47, Fujii Masao wrote:

Thanks for your comments!


Thanks for updating the patch!

PostgreSQL Patch Tester reported that the patched version failed to be 
compiled

at Windows. Could you fix this issue?
https://ci.appveyor.com/project/postgresql-cfbot/postgresql/build/1.0.131238



It seems PGDLLIMPORT was necessary..
Attached a new one.

Regards.diff --git a/contrib/pg_stat_statements/expected/pg_stat_statements.out b/contrib/pg_stat_statements/expected/pg_stat_statements.out
index 16158525ca..887c4b2be8 100644
--- a/contrib/pg_stat_statements/expected/pg_stat_statements.out
+++ b/contrib/pg_stat_statements/expected/pg_stat_statements.out
@@ -251,6 +251,72 @@ FROM pg_stat_statements ORDER BY query COLLATE "C";
  UPDATE pgss_test SET b = $1 WHERE a > $2  | 1 |3 | t   | t | t
 (7 rows)
 
+--
+-- Track the number of generic plan
+--
+CREATE TABLE pgss_test (i int, j int, k int);
+SELECT pg_stat_statements_reset();
+ pg_stat_statements_reset 
+--
+ 
+(1 row)
+
+SET plan_cache_mode TO force_generic_plan;
+SET pg_stat_statements.track_utility = TRUE;
+PREPARE pgss_p1 AS SELECT i FROM pgss_test WHERE i = $1;
+EXECUTE pgss_p1(1);
+ i 
+---
+(0 rows)
+
+-- EXPLAIN ANALZE should be recorded
+PREPARE pgss_p2 AS SELECT j FROM pgss_test WHERE j = $1;
+EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) EXECUTE pgss_p2(1);
+  QUERY PLAN   
+---
+ Seq Scan on pgss_test (actual rows=0 loops=1)
+   Filter: (j = $1)
+(2 rows)
+
+-- Nested Portal
+PREPARE pgss_p3 AS SELECT k FROM pgss_test WHERE k = $1;
+BEGIN;
+DECLARE pgss_c1 CURSOR FOR SELECT name FROM pg_prepared_statements;
+FETCH IN pgss_c1;
+  name   
+-
+ pgss_p2
+(1 row)
+
+EXECUTE pgss_p3(1);
+ k 
+---
+(0 rows)
+
+FETCH IN pgss_c1;
+  name   
+-
+ pgss_p1
+(1 row)
+
+COMMIT;
+SELECT calls, generic_calls, query FROM pg_stat_statements;
+ calls | generic_calls |  query   
+---+---+--
+ 1 | 0 | DECLARE pgss_c1 CURSOR FOR SELECT name FROM pg_prepared_statements
+ 0 | 0 | SELECT calls, generic_calls, query FROM pg_stat_statements
+ 1 | 1 | PREPARE pgss_p1 AS SELECT i FROM pgss_test WHERE i = $1
+ 2 | 0 | FETCH IN pgss_c1
+ 1 | 0 | BEGIN
+ 1 | 0 | SELECT pg_stat_statements_reset()
+ 1 | 1 | EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) EXECUTE pgss_p2(1)
+ 1 | 0 | COMMIT
+ 1 | 1 | PREPARE pgss_p3 AS SELECT k FROM pgss_test WHERE k = $1
+(9 rows)
+
+SET pg_stat_statements.track_utility = FALSE;
+DEALLOCATE ALL;
+DROP TABLE pgss_test;
 --
 -- pg_stat_statements.track = none
 --
diff --git a/contrib/pg_stat_statements/pg_stat_statements--1.7--1.8.sql b/contrib/pg_stat_statements/pg_stat_statements--1.7--1.8.sql
index 0f63f08f7e..7fdef315ae 100644
--- a/contrib/pg_stat_statements/pg_stat_statements--1.7--1.8.sql
+++ b/contrib/pg_stat_statements/pg_stat_statements--1.7--1.8.sql
@@ -44,7 +44,8 @@ CREATE FUNCTION pg_stat_statements(IN showtext boolean,
 OUT blk_write_time float8,
 OUT wal_records int8,
 OUT wal_fpi int8,
-OUT wal_bytes numeric
+OUT wal_bytes numeric,
+OUT generic_calls int8
 )
 RETURNS SETOF record
 AS 'MODULE_PATHNAME', 'pg_stat_statements_1_8'
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 62cccbfa44..b14919c989 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -81,6 +81,7 @@
 #include "utils/acl.h"
 #include "utils/builtins.h"
 #include "utils/memutils.h"
+#include "utils/plancache.h"
 #include "utils/timestamp.h"
 
 PG_MODULE_MAGIC;
@@ -192,6 +193,7 @@ typedef struct Counters
 	int64		wal_records;	/* # of WAL records generated */
 	int64		wal_fpi;		/* # of WAL full page images generated */
 	uint64		wal_bytes;		/* total amount of WAL generated in bytes */
+	int64		generic_calls;	/* # of times generic plans executed */
 } Counters;
 
 /*
@@ -1446,6 +1448,10 @@ pgss_store(const char *query, uint64 queryId,
 			if (e->counters.max_time[kind] < total_time)
 e->counters.max_time[kind] = total_time;
 		}
+
+		if (kind == PGSS_EXEC && is_plan_type_generic)
+			e->counters.generic_calls += 1;
+
 		e->counters.rows += rows;
 		e->counters.shared_blks_hit += bufusage->shared_blks_hit;
 		e->counters.shared_blks_read += bufusage->shared_blks_read;
@@ -1510,8 +1516,8 @@ pg_stat_statements_reset(PG_FUNCTION_ARGS)
 #define PG_STAT_STATEMENTS_COLS_V1_1	18
 #define PG_STAT_STATEMENTS_COLS_V1_2	19
 #define PG_STAT_STATEMENTS_COLS_V1_3	23

Re: Is it useful to record whether plans are generic or custom?

2021-03-25 Thread Fujii Masao




On 2021/03/23 16:32, torikoshia wrote:

On 2021-03-05 17:47, Fujii Masao wrote:

Thanks for your comments!


Thanks for updating the patch!

PostgreSQL Patch Tester reported that the patched version failed to be compiled
at Windows. Could you fix this issue?
https://ci.appveyor.com/project/postgresql-cfbot/postgresql/build/1.0.131238

Regards,

--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION




Re: Is it useful to record whether plans are generic or custom?

2021-03-23 Thread torikoshia

On 2021-03-05 17:47, Fujii Masao wrote:

Thanks for your comments!

I just tried this feature. When I set plan_cache_mode to 
force_generic_plan

and executed the following queries, I found that
pg_stat_statements.generic_calls
and pg_prepared_statements.generic_plans were not the same.
Is this behavior expected? I was thinking that they are basically the 
same.


It's not expected behavior, fixed.



DEALLOCATE ALL;
SELECT pg_stat_statements_reset();
PREPARE hoge AS SELECT * FROM pgbench_accounts WHERE aid = $1;
EXECUTE hoge(1);
EXECUTE hoge(1);
EXECUTE hoge(1);

SELECT generic_plans, statement FROM pg_prepared_statements WHERE
statement LIKE '%hoge%';
 generic_plans |   statement
---+
 3 | PREPARE hoge AS SELECT * FROM pgbench_accounts WHERE 
aid = $1;


SELECT calls, generic_calls, query FROM pg_stat_statements WHERE query
LIKE '%hoge%';
 calls | generic_calls | query
---+---+---
 3 | 2 | PREPARE hoge AS SELECT * FROM
pgbench_accounts WHERE aid = $1




When I executed the prepared statements via EXPLAIN ANALYZE, I found
pg_stat_statements.generic_calls was not incremented. Is this behavior 
expected?

Or we should count generic_calls even when executing the queries via
ProcessUtility()?


I think prepared statements via EXPLAIN ANALYZE also should be counted
for consistency with  pg_prepared_statements.

Since ActivePortal did not keep the plan type in the 
ProcessUtility_hook,

I moved the global variables 'is_plan_type_generic' and
'is_prev_plan_type_generic' from pg_stat_statements to plancache.c.



DEALLOCATE ALL;
SELECT pg_stat_statements_reset();
PREPARE hoge AS SELECT * FROM pgbench_accounts WHERE aid = $1;
EXPLAIN ANALYZE EXECUTE hoge(1);
EXPLAIN ANALYZE EXECUTE hoge(1);
EXPLAIN ANALYZE EXECUTE hoge(1);

SELECT generic_plans, statement FROM pg_prepared_statements WHERE
statement LIKE '%hoge%';
 generic_plans |   statement
---+
 3 | PREPARE hoge AS SELECT * FROM pgbench_accounts WHERE 
aid = $1;


SELECT calls, generic_calls, query FROM pg_stat_statements WHERE query
LIKE '%hoge%';
 calls | generic_calls | query
---+---+---
 3 | 0 | PREPARE hoge AS SELECT * FROM
pgbench_accounts WHERE aid = $1
 3 | 0 | EXPLAIN ANALYZE EXECUTE hoge(1)




Regards,diff --git a/contrib/pg_stat_statements/expected/pg_stat_statements.out b/contrib/pg_stat_statements/expected/pg_stat_statements.out
index 16158525ca..887c4b2be8 100644
--- a/contrib/pg_stat_statements/expected/pg_stat_statements.out
+++ b/contrib/pg_stat_statements/expected/pg_stat_statements.out
@@ -251,6 +251,72 @@ FROM pg_stat_statements ORDER BY query COLLATE "C";
  UPDATE pgss_test SET b = $1 WHERE a > $2  | 1 |3 | t   | t | t
 (7 rows)
 
+--
+-- Track the number of generic plan
+--
+CREATE TABLE pgss_test (i int, j int, k int);
+SELECT pg_stat_statements_reset();
+ pg_stat_statements_reset 
+--
+ 
+(1 row)
+
+SET plan_cache_mode TO force_generic_plan;
+SET pg_stat_statements.track_utility = TRUE;
+PREPARE pgss_p1 AS SELECT i FROM pgss_test WHERE i = $1;
+EXECUTE pgss_p1(1);
+ i 
+---
+(0 rows)
+
+-- EXPLAIN ANALZE should be recorded
+PREPARE pgss_p2 AS SELECT j FROM pgss_test WHERE j = $1;
+EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) EXECUTE pgss_p2(1);
+  QUERY PLAN   
+---
+ Seq Scan on pgss_test (actual rows=0 loops=1)
+   Filter: (j = $1)
+(2 rows)
+
+-- Nested Portal
+PREPARE pgss_p3 AS SELECT k FROM pgss_test WHERE k = $1;
+BEGIN;
+DECLARE pgss_c1 CURSOR FOR SELECT name FROM pg_prepared_statements;
+FETCH IN pgss_c1;
+  name   
+-
+ pgss_p2
+(1 row)
+
+EXECUTE pgss_p3(1);
+ k 
+---
+(0 rows)
+
+FETCH IN pgss_c1;
+  name   
+-
+ pgss_p1
+(1 row)
+
+COMMIT;
+SELECT calls, generic_calls, query FROM pg_stat_statements;
+ calls | generic_calls |  query   
+---+---+--
+ 1 | 0 | DECLARE pgss_c1 CURSOR FOR SELECT name FROM pg_prepared_statements
+ 0 | 0 | SELECT calls, generic_calls, query FROM pg_stat_statements
+ 1 | 1 | PREPARE pgss_p1 AS SELECT i FROM pgss_test WHERE i = $1
+ 2 | 0 | FETCH IN pgss_c1
+ 1 | 0 | BEGIN
+ 1 | 0 | SELECT pg_stat_statements_reset()
+ 1 | 1 | EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) EXECUTE 

Re: Is it useful to record whether plans are generic or custom?

2021-03-05 Thread Fujii Masao




On 2021/02/08 14:02, torikoshia wrote:

On 2021-02-04 11:19, Kyotaro Horiguchi wrote:

At Thu, 04 Feb 2021 10:16:47 +0900, torikoshia
 wrote in

Chengxi Sun, Yamada-san, Horiguchi-san,

Thanks for all your comments.
Adding only the number of generic plan execution seems acceptable.

On Mon, Jan 25, 2021 at 2:10 PM Kyotaro Horiguchi
 wrote:
> Note that ActivePortal is the closest nested portal. So it gives the
> wrong result for nested portals.

I may be wrong, but I thought it was ok since the closest nested
portal is the portal to be executed.


After executing the inner-most portal, is_plan_type_generic has a
value for the inner-most portal and it won't be changed ever after. At
the ExecutorEnd of all the upper-portals see the value for the
inner-most portal left behind is_plan_type_generic nevertheless the
portals at every nest level are independent.


ActivePortal is used in ExecutorStart hook in the patch.
And as far as I read PortalStart(), ActivePortal is changed to the
portal to be executed before ExecutorStart().

If possible, could you tell me the specific case which causes wrong
results?


Running a plpgsql function that does PREPRE in a query that does
PREPARE?


Thanks for your explanation!

I confirmed that it in fact happened.

To avoid it, attached patch preserves the is_plan_type_generic before changing 
it and sets it back at the end of pgss_ExecutorEnd().

Any thoughts?


I just tried this feature. When I set plan_cache_mode to force_generic_plan
and executed the following queries, I found that 
pg_stat_statements.generic_calls
and pg_prepared_statements.generic_plans were not the same.
Is this behavior expected? I was thinking that they are basically the same.


DEALLOCATE ALL;
SELECT pg_stat_statements_reset();
PREPARE hoge AS SELECT * FROM pgbench_accounts WHERE aid = $1;
EXECUTE hoge(1);
EXECUTE hoge(1);
EXECUTE hoge(1);

SELECT generic_plans, statement FROM pg_prepared_statements WHERE statement 
LIKE '%hoge%';
 generic_plans |   statement
---+
 3 | PREPARE hoge AS SELECT * FROM pgbench_accounts WHERE aid = $1;

SELECT calls, generic_calls, query FROM pg_stat_statements WHERE query LIKE 
'%hoge%';
 calls | generic_calls | query
---+---+---
 3 | 2 | PREPARE hoge AS SELECT * FROM pgbench_accounts WHERE 
aid = $1




When I executed the prepared statements via EXPLAIN ANALYZE, I found
pg_stat_statements.generic_calls was not incremented. Is this behavior expected?
Or we should count generic_calls even when executing the queries via 
ProcessUtility()?

DEALLOCATE ALL;
SELECT pg_stat_statements_reset();
PREPARE hoge AS SELECT * FROM pgbench_accounts WHERE aid = $1;
EXPLAIN ANALYZE EXECUTE hoge(1);
EXPLAIN ANALYZE EXECUTE hoge(1);
EXPLAIN ANALYZE EXECUTE hoge(1);

SELECT generic_plans, statement FROM pg_prepared_statements WHERE statement 
LIKE '%hoge%';
 generic_plans |   statement
---+
 3 | PREPARE hoge AS SELECT * FROM pgbench_accounts WHERE aid = $1;

SELECT calls, generic_calls, query FROM pg_stat_statements WHERE query LIKE 
'%hoge%';
 calls | generic_calls | query
---+---+---
 3 | 0 | PREPARE hoge AS SELECT * FROM pgbench_accounts WHERE 
aid = $1
 3 | 0 | EXPLAIN ANALYZE EXECUTE hoge(1)


Regards,

--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION




Re: Is it useful to record whether plans are generic or custom?

2021-03-05 Thread Fujii Masao




On 2021/01/28 8:11, Tatsuro Yamada wrote:

Hi Toricoshi-san,

On 2021/01/12 20:36, torikoshia wrote:

I suppose it would be normal practice to store past results of
pg_stat_statements for future comparisons.
If this is the case, I think that if we only add the number of
generic plan execution, it will give us a hint to notice the cause
of performance degradation due to changes in the plan between
generic and custom.

For example, if there is a clear difference in the number of times
the generic plan is executed between before and after performance
degradation as below, it would be natural to check if there is a
problem with the generic plan.

...

Attached a patch that just adds a generic call counter to
pg_stat_statements.



I think that I'd like to use the view when we faced a performance
problem and find the reason. If we did the fixed-point observation
(should I say time-series analysis?) of generic_calls, it allows us to
realize the counter changes, and we can know whether the suspect is
generic_plan or not. So the patch helps DBA, I believe.


In that use case maybe what you actually want to see is whether the plan was
changed or not, rather than whether generic plan or custom plan is used?
If so, it's better to expose seq_scan (num of sequential scans processed by
the query) and idx_scan (num of index scans processed by the query) like
pg_stat_all_tables, per query in pg_stat_statements?

Regards,

--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION




Re: Is it useful to record whether plans are generic or custom?

2021-02-07 Thread torikoshia

On 2021-02-04 11:19, Kyotaro Horiguchi wrote:

At Thu, 04 Feb 2021 10:16:47 +0900, torikoshia
 wrote in

Chengxi Sun, Yamada-san, Horiguchi-san,

Thanks for all your comments.
Adding only the number of generic plan execution seems acceptable.

On Mon, Jan 25, 2021 at 2:10 PM Kyotaro Horiguchi
 wrote:
> Note that ActivePortal is the closest nested portal. So it gives the
> wrong result for nested portals.

I may be wrong, but I thought it was ok since the closest nested
portal is the portal to be executed.


After executing the inner-most portal, is_plan_type_generic has a
value for the inner-most portal and it won't be changed ever after. At
the ExecutorEnd of all the upper-portals see the value for the
inner-most portal left behind is_plan_type_generic nevertheless the
portals at every nest level are independent.


ActivePortal is used in ExecutorStart hook in the patch.
And as far as I read PortalStart(), ActivePortal is changed to the
portal to be executed before ExecutorStart().

If possible, could you tell me the specific case which causes wrong
results?


Running a plpgsql function that does PREPRE in a query that does
PREPARE?


Thanks for your explanation!

I confirmed that it in fact happened.

To avoid it, attached patch preserves the is_plan_type_generic before 
changing it and sets it back at the end of pgss_ExecutorEnd().


Any thoughts?


Regards,

--
Atsushi Torikoshidiff --git a/contrib/pg_stat_statements/pg_stat_statements--1.7--1.8.sql b/contrib/pg_stat_statements/pg_stat_statements--1.7--1.8.sql
index 0f63f08f7e..7fdef315ae 100644
--- a/contrib/pg_stat_statements/pg_stat_statements--1.7--1.8.sql
+++ b/contrib/pg_stat_statements/pg_stat_statements--1.7--1.8.sql
@@ -44,7 +44,8 @@ CREATE FUNCTION pg_stat_statements(IN showtext boolean,
 OUT blk_write_time float8,
 OUT wal_records int8,
 OUT wal_fpi int8,
-OUT wal_bytes numeric
+OUT wal_bytes numeric,
+OUT generic_calls int8
 )
 RETURNS SETOF record
 AS 'MODULE_PATHNAME', 'pg_stat_statements_1_8'
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 62cccbfa44..f5801016d6 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -77,10 +77,12 @@
 #include "storage/fd.h"
 #include "storage/ipc.h"
 #include "storage/spin.h"
+#include "tcop/pquery.h"
 #include "tcop/utility.h"
 #include "utils/acl.h"
 #include "utils/builtins.h"
 #include "utils/memutils.h"
+#include "utils/plancache.h"
 #include "utils/timestamp.h"
 
 PG_MODULE_MAGIC;
@@ -192,6 +194,7 @@ typedef struct Counters
 	int64		wal_records;	/* # of WAL records generated */
 	int64		wal_fpi;		/* # of WAL full page images generated */
 	uint64		wal_bytes;		/* total amount of WAL generated in bytes */
+	int64		generic_calls;	/* # of times generic plans executed */
 } Counters;
 
 /*
@@ -277,6 +280,10 @@ static int	exec_nested_level = 0;
 /* Current nesting depth of planner calls */
 static int	plan_nested_level = 0;
 
+/* Current and previous plan type */
+static bool	is_plan_type_generic = false;
+static bool	is_prev_plan_type_generic = false;
+
 /* Saved hook values in case of unload */
 static shmem_startup_hook_type prev_shmem_startup_hook = NULL;
 static post_parse_analyze_hook_type prev_post_parse_analyze_hook = NULL;
@@ -1034,6 +1041,23 @@ pgss_ExecutorStart(QueryDesc *queryDesc, int eflags)
 	 */
 	if (pgss_enabled(exec_nested_level) && queryDesc->plannedstmt->queryId != UINT64CONST(0))
 	{
+		/*
+		 * Since ActivePortal is not available at ExecutorEnd, we preserve
+		 * the current and previous plan type here.
+		 * Previous one is necessary since portals can be nested.
+		 */
+		Assert(ActivePortal);
+
+		is_prev_plan_type_generic = is_plan_type_generic;
+
+		if (ActivePortal->cplan)
+		{
+			if (ActivePortal->cplan->is_generic)
+is_plan_type_generic = true;
+			else
+is_plan_type_generic = false;
+		}
+
 		/*
 		 * Set up to track total elapsed time in ExecutorRun.  Make sure the
 		 * space is allocated in the per-query context so it will go away at
@@ -1122,6 +1146,9 @@ pgss_ExecutorEnd(QueryDesc *queryDesc)
    NULL);
 	}
 
+	/* Storing has done. Set is_plan_type_generic back to the original. */
+	is_plan_type_generic = is_prev_plan_type_generic;
+
 	if (prev_ExecutorEnd)
 		prev_ExecutorEnd(queryDesc);
 	else
@@ -1427,6 +1454,8 @@ pgss_store(const char *query, uint64 queryId,
 			e->counters.max_time[kind] = total_time;
 			e->counters.mean_time[kind] = total_time;
 		}
+		else if (kind == PGSS_EXEC && is_plan_type_generic)
+			e->counters.generic_calls += 1;
 		else
 		{
 			/*
@@ -1510,8 +1539,8 @@ pg_stat_statements_reset(PG_FUNCTION_ARGS)
 #define PG_STAT_STATEMENTS_COLS_V1_1	18
 #define PG_STAT_STATEMENTS_COLS_V1_2	19
 #define PG_STAT_STATEMENTS_COLS_V1_3	23
-#define PG_STAT_STATEMENTS_COLS_V1_8	32
-#define PG_STAT_STATEMENTS_COLS			32	/* maximum of above */
+#define PG_STAT_STATEMENTS_COLS_V1_8	33
+#define 

Re: Is it useful to record whether plans are generic or custom?

2021-02-03 Thread Kyotaro Horiguchi
At Thu, 04 Feb 2021 10:16:47 +0900, torikoshia  
wrote in 
> Chengxi Sun, Yamada-san, Horiguchi-san,
> 
> Thanks for all your comments.
> Adding only the number of generic plan execution seems acceptable.
> 
> On Mon, Jan 25, 2021 at 2:10 PM Kyotaro Horiguchi
>  wrote:
> > Note that ActivePortal is the closest nested portal. So it gives the
> > wrong result for nested portals.
> 
> I may be wrong, but I thought it was ok since the closest nested
> portal is the portal to be executed.

After executing the inner-most portal, is_plan_type_generic has a
value for the inner-most portal and it won't be changed ever after. At
the ExecutorEnd of all the upper-portals see the value for the
inner-most portal left behind is_plan_type_generic nevertheless the
portals at every nest level are indenpendent.

> ActivePortal is used in ExecutorStart hook in the patch.
> And as far as I read PortalStart(), ActivePortal is changed to the
> portal to be executed before ExecutorStart().
> 
> If possible, could you tell me the specific case which causes wrong
> results?

Running a plpgsql function that does PREPRE in a query that does
PREPARE?

regards.

-- 
Kyotaro Horiguchi
NTT Open Source Software Center




Re: Is it useful to record whether plans are generic or custom?

2021-02-03 Thread torikoshia

Chengxi Sun, Yamada-san, Horiguchi-san,

Thanks for all your comments.
Adding only the number of generic plan execution seems acceptable.

On Mon, Jan 25, 2021 at 2:10 PM Kyotaro Horiguchi 
 wrote:

Note that ActivePortal is the closest nested portal. So it gives the
wrong result for nested portals.


I may be wrong, but I thought it was ok since the closest nested portal 
is the portal to be executed.


ActivePortal is used in ExecutorStart hook in the patch.
And as far as I read PortalStart(), ActivePortal is changed to the 
portal to be executed before ExecutorStart().


If possible, could you tell me the specific case which causes wrong 
results?


Regards,

--
Atsushi Torikoshi




Re: Is it useful to record whether plans are generic or custom?

2021-01-27 Thread Tatsuro Yamada

Hi Toricoshi-san,

On 2021/01/12 20:36, torikoshia wrote:

I suppose it would be normal practice to store past results of
pg_stat_statements for future comparisons.
If this is the case, I think that if we only add the number of
generic plan execution, it will give us a hint to notice the cause
of performance degradation due to changes in the plan between
generic and custom.

For example, if there is a clear difference in the number of times
the generic plan is executed between before and after performance
degradation as below, it would be natural to check if there is a
problem with the generic plan.

...

Attached a patch that just adds a generic call counter to
pg_stat_statements.



I think that I'd like to use the view when we faced a performance
problem and find the reason. If we did the fixed-point observation
(should I say time-series analysis?) of generic_calls, it allows us to
realize the counter changes, and we can know whether the suspect is
generic_plan or not. So the patch helps DBA, I believe.

Regards,
Tatsuro Yamada





Re: Is it useful to record whether plans are generic or custom?

2021-01-27 Thread Tatsuro Yamada

Horiguchi-san,

On 2020/12/04 15:37, Kyotaro Horiguchi wrote:

And I'm also struggling with the following.

| However, I also began to wonder how effective it would be to just
| distinguish between generic and custom plans.  Custom plans can
| include all sorts of plans. and thinking cache validation, generic
| plans can also include various plans.

| Considering this, I'm starting to feel that it would be better to
| not just keeping whether generic or cutom but the plan itself as
| discussed in the below thread.


FWIW, that seems to me to be like some existing extension modules,
pg_stat_plans or pg_store_plans..  The former is faster but may lose
plans, the latter doesn't lose plans but slower.  I feel that we'd
beter consider simpler feature if we are intendeng it to be a part of
a contrib module,


There is also pg_show_plans.
Ideally, it would be better to able to track all of the plan changes by
checking something view since Plan Stability is important for DBA when
they use PostgreSQL in Mission-critical systems.
I prefer that the feature will be released as a contrib module. :-D

Regards,
Tatsuro Yamada
 






Re: Is it useful to record whether plans are generic or custom?

2021-01-27 Thread Tatsuro Yamada

Torikoshi-san,

On 2020/12/04 15:03, torikoshia wrote:


ISTM now that creating pg_stat_statements_xxx views
both for generic andcustom plans is better than my PoC patch.

And I'm also struggling with the following.

| However, I also began to wonder how effective it would be to just
| distinguish between generic and custom plans.  Custom plans can
| include all sorts of plans. and thinking cache validation, generic
| plans can also include various plans.

| Considering this, I'm starting to feel that it would be better to
| not just keeping whether generic or cutom but the plan itself as
| discussed in the below thread.


Yamada-san,

Do you think it's effective just distinguish between generic
and custom plans?


Sorry for the super delayed replay.

Ah, it's okay.
It would be better to check both info by using a single view from the
perspective of usability. However, it's okay to divide both information
into two views to use memory effectively.

Regards,
Tatsuro Yamada





Re: Is it useful to record whether plans are generic or custom?

2021-01-27 Thread Tatsuro Yamada

On 2020/12/04 14:29, Fujii Masao wrote:


On 2020/11/30 15:24, Tatsuro Yamada wrote:

Hi Torikoshi-san,



In this patch, exposing new columns is mandatory, but I think
it's better to make it optional by adding a GUC something
like 'pgss.track_general_custom_plans.

I also feel it makes the number of columns too many.
Just adding the total time may be sufficient.



I think this feature is useful for DBA. So I hope that it gets
committed to PG14. IMHO, many columns are Okay because DBA can
select specific columns by their query.
Therefore, it would be better to go with the current design.


But that design may waste lots of memory. No? For example, when
plan_cache_mode=force_custom_plan, the memory used for the columns
for generic plans is not used.

Regards,



Sorry for the super delayed replay.
I don't think that because I suppose that DBA uses plan_cache_mode if
they faced an inefficient execution plan. And the parameter will be used
as a session-level GUC parameter, not a database-level.


Regards,
Tatsuro Yamada







Re: Is it useful to record whether plans are generic or custom?

2021-01-24 Thread Kyotaro Horiguchi
At Tue, 12 Jan 2021 20:36:58 +0900, torikoshia  
wrote in 
> I suppose it would be normal practice to store past results of
> pg_stat_statements for future comparisons.
> If this is the case, I think that if we only add the number of
> generic plan execution, it will give us a hint to notice the cause
> of performance degradation due to changes in the plan between
> generic and custom.

Agreed.

> Attached a patch that just adds a generic call counter to
> pg_stat_statements.
> 
> Any thoughts?

Note that ActivePortal is the closest nested portal. So it gives the
wrong result for nested portals.

regards.

-- 
Kyotaro Horiguchi
NTT Open Source Software Center




Re: Is it useful to record whether plans are generic or custom?

2021-01-22 Thread Chengxi Sun
The following review has been posted through the commitfest application:
make installcheck-world:  tested, failed
Implements feature:   tested, failed
Spec compliant:   not tested
Documentation:not tested

Hi Atsushi,

I just run a few test on your latest patch. It works well. I agree with you, I 
think just tracking generic_calls is enough to get the reason of performance 
change from pg_stat_statements. I mean if you need more detailed information 
about the plan and execution of prepared statements, it is better to store this 
information in a separate view. It seems more reasonable to me.

Regards,

Re: Is it useful to record whether plans are generic or custom?

2021-01-12 Thread torikoshia

 wrote in



ISTM now that creating pg_stat_statements_xxx views
both for generic andcustom plans is better than my PoC patch.


On my second thought, it also makes pg_stat_statements too complicated
compared to what it makes possible..

I'm also worrying that whether taking generic and custom plan execution
time or not would be controlled by a GUC variable, and the default
would be not taking them.
Not many people will change the default.

Since the same queryid can contain various queries (different plan,
different parameter $n, etc.), I also started to feel that it is not
appropriate to get the execution time of only generic/custom queries
separately.

I suppose it would be normal practice to store past results of
pg_stat_statements for future comparisons.
If this is the case, I think that if we only add the number of
generic plan execution, it will give us a hint to notice the cause
of performance degradation due to changes in the plan between
generic and custom.

For example, if there is a clear difference in the number of times
the generic plan is executed between before and after performance
degradation as below, it would be natural to check if there is a
problem with the generic plan.

  [after performance degradation]
  =# SELECT query, calls, generic_calls FROM pg_stat_statements where 
query like '%t1%';

  query| calls | generic_calls
  -+---+---
   PREPARE p1 as select * from t1 where i = $1 |  1100 |50

  [before performance degradation]
  =# SELECT query, calls, generic_calls FROM pg_stat_statements where 
query like '%t1%';

  query| calls | generic_calls
  -+---+---
   PREPARE p1 as select * from t1 where i = $1 |  1000 | 0


Attached a patch that just adds a generic call counter to
pg_stat_statements.

Any thoughts?


Regards,

--
Atsushi Torikoshidiff --git a/contrib/pg_stat_statements/pg_stat_statements--1.7--1.8.sql b/contrib/pg_stat_statements/pg_stat_statements--1.7--1.8.sql
index 0f63f08f7e..7fdef315ae 100644
--- a/contrib/pg_stat_statements/pg_stat_statements--1.7--1.8.sql
+++ b/contrib/pg_stat_statements/pg_stat_statements--1.7--1.8.sql
@@ -44,7 +44,8 @@ CREATE FUNCTION pg_stat_statements(IN showtext boolean,
 OUT blk_write_time float8,
 OUT wal_records int8,
 OUT wal_fpi int8,
-OUT wal_bytes numeric
+OUT wal_bytes numeric,
+OUT generic_calls int8
 )
 RETURNS SETOF record
 AS 'MODULE_PATHNAME', 'pg_stat_statements_1_8'
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 72a117fc19..171c39f857 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -77,10 +77,12 @@
 #include "storage/fd.h"
 #include "storage/ipc.h"
 #include "storage/spin.h"
+#include "tcop/pquery.h"
 #include "tcop/utility.h"
 #include "utils/acl.h"
 #include "utils/builtins.h"
 #include "utils/memutils.h"
+#include "utils/plancache.h"
 #include "utils/timestamp.h"
 
 PG_MODULE_MAGIC;
@@ -192,6 +194,7 @@ typedef struct Counters
 	int64		wal_records;	/* # of WAL records generated */
 	int64		wal_fpi;		/* # of WAL full page images generated */
 	uint64		wal_bytes;		/* total amount of WAL generated in bytes */
+	int64		generic_calls;	/* # of times generic plans executed */
 } Counters;
 
 /*
@@ -277,6 +280,9 @@ static int	exec_nested_level = 0;
 /* Current nesting depth of planner calls */
 static int	plan_nested_level = 0;
 
+/* Current plan type */
+static bool	is_plan_type_generic = false;
+
 /* Saved hook values in case of unload */
 static shmem_startup_hook_type prev_shmem_startup_hook = NULL;
 static post_parse_analyze_hook_type prev_post_parse_analyze_hook = NULL;
@@ -1034,6 +1040,20 @@ pgss_ExecutorStart(QueryDesc *queryDesc, int eflags)
 	 */
 	if (pgss_enabled(exec_nested_level) && queryDesc->plannedstmt->queryId != UINT64CONST(0))
 	{
+		/*
+		 * Since ActivePortal is not available at ExecutorEnd, we preserve
+		 * the plan type here.
+		 */
+		Assert(ActivePortal);
+
+		if (ActivePortal->cplan)
+		{
+			if (ActivePortal->cplan->is_generic)
+is_plan_type_generic = true;
+			else
+is_plan_type_generic = false;
+		}
+
 		/*
 		 * Set up to track total elapsed time in ExecutorRun.  Make sure the
 		 * space is allocated in the per-query context so it will go away at
@@ -1427,6 +1447,8 @@ pgss_store(const char *query, uint64 queryId,
 			e->counters.max_time[kind] = total_time;
 			e->counters.mean_time[kind] = total_time;
 		}
+		else if (kind == PGSS_EXEC && is_plan_type_generic)
+			e->counters.generic_calls += 1;
 		else
 		{
 			/*
@@ -1510,8 +1532,8 @@ pg_stat_statements_reset(PG_FUNCTION_ARGS)
 #define PG_STAT_STATEMENTS_COLS_V1_1	18
 #define PG_STAT_STATEMENTS_COLS_V1_2	19
 #define PG_STAT_STATEMENTS_COLS_V1_3	23
-#define 

Re: Is it useful to record whether plans are generic or custom?

2020-12-03 Thread Kyotaro Horiguchi
At Fri, 04 Dec 2020 15:03:25 +0900, torikoshia  
wrote in 
> On 2020-12-04 14:29, Fujii Masao wrote:
> > On 2020/11/30 15:24, Tatsuro Yamada wrote:
> >> Hi Torikoshi-san,
> >> 
> >>> In this patch, exposing new columns is mandatory, but I think
> >>> it's better to make it optional by adding a GUC something
> >>> like 'pgss.track_general_custom_plans.
> >>> I also feel it makes the number of columns too many.
> >>> Just adding the total time may be sufficient.
> >> I think this feature is useful for DBA. So I hope that it gets
> >> committed to PG14. IMHO, many columns are Okay because DBA can
> >> select specific columns by their query.
> >> Therefore, it would be better to go with the current design.
> > But that design may waste lots of memory. No? For example, when
> > plan_cache_mode=force_custom_plan, the memory used for the columns
> > for generic plans is not used.
> > 
> 
> Yeah.
> 
> ISTM now that creating pg_stat_statements_xxx views
> both for generic andcustom plans is better than my PoC patch.
> 
> And I'm also struggling with the following.
> 
> | However, I also began to wonder how effective it would be to just
> | distinguish between generic and custom plans.  Custom plans can
> | include all sorts of plans. and thinking cache validation, generic
> | plans can also include various plans.
> 
> | Considering this, I'm starting to feel that it would be better to
> | not just keeping whether generic or cutom but the plan itself as
> | discussed in the below thread.

FWIW, that seems to me to be like some existing extension modules,
pg_stat_plans or pg_store_plans..  The former is faster but may lose
plans, the latter doesn't lose plans but slower.  I feel that we'd
beter consider simpler feature if we are intendeng it to be a part of
a contrib module,

> Yamada-san,
> 
> Do you think it's effective just distinguish between generic
> and custom plans?
> 
> Regards,

regards.

-- 
Kyotaro Horiguchi
NTT Open Source Software Center




Re: Is it useful to record whether plans are generic or custom?

2020-12-03 Thread torikoshia

On 2020-12-04 14:29, Fujii Masao wrote:

On 2020/11/30 15:24, Tatsuro Yamada wrote:

Hi Torikoshi-san,



In this patch, exposing new columns is mandatory, but I think
it's better to make it optional by adding a GUC something
like 'pgss.track_general_custom_plans.

I also feel it makes the number of columns too many.
Just adding the total time may be sufficient.



I think this feature is useful for DBA. So I hope that it gets
committed to PG14. IMHO, many columns are Okay because DBA can
select specific columns by their query.
Therefore, it would be better to go with the current design.


But that design may waste lots of memory. No? For example, when
plan_cache_mode=force_custom_plan, the memory used for the columns
for generic plans is not used.



Yeah.

ISTM now that creating pg_stat_statements_xxx views
both for generic andcustom plans is better than my PoC patch.

And I'm also struggling with the following.

| However, I also began to wonder how effective it would be to just
| distinguish between generic and custom plans.  Custom plans can
| include all sorts of plans. and thinking cache validation, generic
| plans can also include various plans.

| Considering this, I'm starting to feel that it would be better to
| not just keeping whether generic or cutom but the plan itself as
| discussed in the below thread.


Yamada-san,

Do you think it's effective just distinguish between generic
and custom plans?

Regards,




Re: Is it useful to record whether plans are generic or custom?

2020-12-03 Thread Fujii Masao




On 2020/11/30 15:24, Tatsuro Yamada wrote:

Hi Torikoshi-san,



In this patch, exposing new columns is mandatory, but I think
it's better to make it optional by adding a GUC something
like 'pgss.track_general_custom_plans.

I also feel it makes the number of columns too many.
Just adding the total time may be sufficient.



I think this feature is useful for DBA. So I hope that it gets
committed to PG14. IMHO, many columns are Okay because DBA can
select specific columns by their query.
Therefore, it would be better to go with the current design.


But that design may waste lots of memory. No? For example, when
plan_cache_mode=force_custom_plan, the memory used for the columns
for generic plans is not used.

Regards,

--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION




Re: Is it useful to record whether plans are generic or custom?

2020-11-29 Thread Tatsuro Yamada

Hi Torikoshi-san,



In this patch, exposing new columns is mandatory, but I think
it's better to make it optional by adding a GUC something
like 'pgss.track_general_custom_plans.

I also feel it makes the number of columns too many.
Just adding the total time may be sufficient.



I think this feature is useful for DBA. So I hope that it gets
committed to PG14. IMHO, many columns are Okay because DBA can
select specific columns by their query.
Therefore, it would be better to go with the current design.

I did the regression test using your patch on 7e5e1bba03, and
it failed unfortunately. See below:

===
 122 of 201 tests failed, 1 of these failures ignored.
===
...
2020-11-30 09:45:18.160 JST [12977] LOG:  database system was not
properly shut down; automatic recovery in progress


Regards,
Tatsuro Yamada






Re: Is it useful to record whether plans are generic or custom?

2020-11-17 Thread Pavel Stehule
út 17. 11. 2020 v 15:21 odesílatel torikoshia 
napsal:

> On 2020-11-12 14:23, Pavel Stehule wrote:
>
> > yes, the plan self is very interesting information - and information
> > if plan was generic or not is interesting too. It is other dimension
> > of query - maybe there can be rule - for any query store max 100 most
> > slows plans with all attributes. The next issue is fact so first first
> > 5 execution of generic plans are not generic in real. This fact should
> > be visible too.
>
> Thanks!
> However, AFAIU, we can know whether the plan type is generic or custom
> from the plan information as described in the manual.
>
> -- https://www.postgresql.org/docs/devel/sql-prepare.html
> > If a generic plan is in use, it will contain parameter symbols $n,
> > while a custom plan will have the supplied parameter values substituted
> > into it.
>
> If we can get the plan information, the case like 'first 5 execution
> of generic plans are not generic in real' does not happen, doesn't it?
>

yes

postgres=# create table foo(a int);
CREATE TABLE
postgres=# prepare x as select * from foo where a = $1;
PREPARE
postgres=# explain execute x(10);
┌─┐
│ QUERY PLAN  │
╞═╡
│ Seq Scan on foo  (cost=0.00..41.88 rows=13 width=4) │
│   Filter: (a = 10)  │
└─┘
(2 rows)

postgres=# explain execute x(10);
┌─┐
│ QUERY PLAN  │
╞═╡
│ Seq Scan on foo  (cost=0.00..41.88 rows=13 width=4) │
│   Filter: (a = 10)  │
└─┘
(2 rows)

postgres=# explain execute x(10);
┌─┐
│ QUERY PLAN  │
╞═╡
│ Seq Scan on foo  (cost=0.00..41.88 rows=13 width=4) │
│   Filter: (a = 10)  │
└─┘
(2 rows)

postgres=# explain execute x(10);
┌─┐
│ QUERY PLAN  │
╞═╡
│ Seq Scan on foo  (cost=0.00..41.88 rows=13 width=4) │
│   Filter: (a = 10)  │
└─┘
(2 rows)

postgres=# explain execute x(10);
┌─┐
│ QUERY PLAN  │
╞═╡
│ Seq Scan on foo  (cost=0.00..41.88 rows=13 width=4) │
│   Filter: (a = 10)  │
└─┘
(2 rows)

postgres=# explain execute x(10);
┌─┐
│ QUERY PLAN  │
╞═╡
│ Seq Scan on foo  (cost=0.00..41.88 rows=13 width=4) │
│   Filter: (a = $1)  │
└─┘
(2 rows)

postgres=# explain execute x(10);
┌─┐
│ QUERY PLAN  │
╞═╡
│ Seq Scan on foo  (cost=0.00..41.88 rows=13 width=4) │
│   Filter: (a = $1)  │
└─┘
(2 rows)


>
> Regards,
>
> --
> Atsushi Torikoshi
>


Re: Is it useful to record whether plans are generic or custom?

2020-11-17 Thread torikoshia

On 2020-11-12 14:23, Pavel Stehule wrote:


yes, the plan self is very interesting information - and information
if plan was generic or not is interesting too. It is other dimension
of query - maybe there can be rule - for any query store max 100 most
slows plans with all attributes. The next issue is fact so first first
5 execution of generic plans are not generic in real. This fact should
be visible too.


Thanks!
However, AFAIU, we can know whether the plan type is generic or custom
from the plan information as described in the manual.

-- https://www.postgresql.org/docs/devel/sql-prepare.html
If a generic plan is in use, it will contain parameter symbols $n, 
while a custom plan will have the supplied parameter values substituted 
into it.


If we can get the plan information, the case like 'first 5 execution
of generic plans are not generic in real' does not happen, doesn't it?


Regards,

--
Atsushi Torikoshi




Re: Is it useful to record whether plans are generic or custom?

2020-11-11 Thread Pavel Stehule
čt 12. 11. 2020 v 2:50 odesílatel torikoshia 
napsal:

> On 2020-09-29 02:39, legrand legrand wrote:
> > Hi Atsushi,
> >
> > +1: Your proposal is a good answer for time based performance analysis
> > (even if parsing durationor blks are not differentiated) .
> >
> > As it makes pgss number of columns wilder, may be an other solution
> > would be to create a pg_stat_statements_xxx view with the same key
> > as pgss (dbid,userid,queryid) and all thoses new counters.
>
> Thanks for your ideas and sorry for my late reply.
>
> It seems creating pg_stat_statements_xxx views both for generic and
> custom plans is better than my PoC patch.
>
> However, I also began to wonder how effective it would be to just
> distinguish between generic and custom plans.  Custom plans can
> include all sorts of plans. and thinking cache validation, generic
> plans can also include various plans.
>
> Considering this, I'm starting to feel that it would be better to
> not just keeping whether generic or cutom but the plan itself as
> discussed in the below thread.
>
>
> https://www.postgresql.org/message-id/flat/CAKU4AWq5_jx1Vyai0_Sumgn-Ks0R%2BN80cf%2Bt170%2BzQs8x6%3DHew%40mail.gmail.com#f57e64b8d37697c808e4385009340871
>
>
> Any thoughts?
>

yes, the plan self is very interesting information - and information if
plan was generic or not is interesting too. It is other dimension of query
- maybe there can be rule - for any query store max 100 most slows plans
with all attributes. The next issue is fact so first first 5 execution of
generic plans are not generic in real. This fact should be visible too.

Regards

Pavel



>
> Regards,
>
> --
> Atsushi Torikoshi
>
>
>


Re: Is it useful to record whether plans are generic or custom?

2020-11-11 Thread torikoshia

On 2020-09-29 02:39, legrand legrand wrote:

Hi Atsushi,

+1: Your proposal is a good answer for time based performance analysis
(even if parsing durationor blks are not differentiated) .

As it makes pgss number of columns wilder, may be an other solution
would be to create a pg_stat_statements_xxx view with the same key
as pgss (dbid,userid,queryid) and all thoses new counters.


Thanks for your ideas and sorry for my late reply.

It seems creating pg_stat_statements_xxx views both for generic and
custom plans is better than my PoC patch.

However, I also began to wonder how effective it would be to just
distinguish between generic and custom plans.  Custom plans can
include all sorts of plans. and thinking cache validation, generic
plans can also include various plans.

Considering this, I'm starting to feel that it would be better to
not just keeping whether generic or cutom but the plan itself as
discussed in the below thread.

https://www.postgresql.org/message-id/flat/CAKU4AWq5_jx1Vyai0_Sumgn-Ks0R%2BN80cf%2Bt170%2BzQs8x6%3DHew%40mail.gmail.com#f57e64b8d37697c808e4385009340871


Any thoughts?


Regards,

--
Atsushi Torikoshi




Re: Is it useful to record whether plans are generic or custom?

2020-09-28 Thread legrand legrand
Hi Atsushi,

+1: Your proposal is a good answer for time based performance analysis 
(even if parsing durationor blks are not differentiated) .

As it makes pgss number of columns wilder, may be an other solution 
would be to create a pg_stat_statements_xxx view with the same key 
as pgss (dbid,userid,queryid) and all thoses new counters.

And last solution would be to display only generic counters, 
because in most cases (and per default) executions are custom ones 
(and generic counters = 0).
if not (when generic counters != 0), customs ones could be deducted from 
total_exec_time - total_generic_time, calls - generic_calls.

Good luck for this feature development
Regards
PAscal



--
Sent from: https://www.postgresql-archive.org/PostgreSQL-hackers-f1928748.html




Re: Is it useful to record whether plans are generic or custom?

2020-09-28 Thread torikoshia

On 2020-09-17 13:46, Michael Paquier wrote:

On Fri, Jul 31, 2020 at 06:47:48PM +0900, torikoshia wrote:

Oops, sorry about that.
I just fixed it there for now.


The regression tests of the patch look unstable, and the CF bot is
reporting a failure here:
https://travis-ci.org/github/postgresql-cfbot/postgresql/builds/727833416
--
Michael



Thank you for letting me know!


I'd like to reach a basic agreement on how we expose the
generic/custom plan information in pgss first.

Given the discussion so far, adding a new attribute to pgss key
is not appropriate since it can easily increase the number of
entries in pgss.

OTOH, just exposing the number of times generic/custom plan was
chosen seems not enough to know whether performance is degraded.

I'm now thinking about exposing not only the number of times
generic/custom plan was chosen but also some performance
metrics like 'total_time' for both generic and custom plans.

Attached a poc patch which exposes total, min, max, mean and
stddev time for both generic and custom plans.


  =# SELECT * FROM =# SELECT * FROM pg_stat_statements;
  -[ RECORD 1 
]---+-

  userid  | 10
  dbid| 12878
  queryid | 4617094108938234366
  query   | PREPARE pr1 AS SELECT * FROM pg_class WHERE 
relname = $1

  plans   | 0
  total_plan_time | 0
  min_plan_time   | 0
  max_plan_time   | 0
  mean_plan_time  | 0
  stddev_plan_time| 0
  calls   | 6
  total_exec_time | 0.466006995
  min_exec_time   | 0.0293760003
  max_exec_time   | 0.237413
  mean_exec_time  | 0.077667834
  stddev_exec_time| 0.07254973134206326
  generic_calls   | 1
  total_generic_time  | 0.0453340006
  min_generic_time| 0.0453340006
  max_generic_time| 0.0453340006
  mean_generic_time   | 0.0453340006
  stddev_generic_time | 0
  custom_calls| 5
  total_custom_time   | 0.420672996
  min_custom_time | 0.0293760003
  max_custom_time | 0.237413
  mean_custom_time| 0.0841346
  stddev_custom_time  | 0.07787966226583164
  ...

In this patch, exposing new columns is mandatory, but I think
it's better to make it optional by adding a GUC something
like 'pgss.track_general_custom_plans.

I also feel it makes the number of columns too many.
Just adding the total time may be sufficient.


Any thoughts?


Regards,

--
Atsushi Torikoshidiff --git a/contrib/pg_stat_statements/pg_stat_statements--1.7--1.8.sql b/contrib/pg_stat_statements/pg_stat_statements--1.7--1.8.sql
index 0f63f08f7e..d118422b2a 100644
--- a/contrib/pg_stat_statements/pg_stat_statements--1.7--1.8.sql
+++ b/contrib/pg_stat_statements/pg_stat_statements--1.7--1.8.sql
@@ -29,6 +29,18 @@ CREATE FUNCTION pg_stat_statements(IN showtext boolean,
 OUT max_exec_time float8,
 OUT mean_exec_time float8,
 OUT stddev_exec_time float8,
+OUT generic_calls int8,
+OUT total_generic_time float8,
+OUT min_generic_time float8,
+OUT max_generic_time float8,
+OUT mean_generic_time float8,
+OUT stddev_generic_time float8,
+OUT custom_calls int8,
+OUT total_custom_time float8,
+OUT min_custom_time float8,
+OUT max_custom_time float8,
+OUT mean_custom_time float8,
+OUT stddev_custom_time float8,
 OUT rows int8,
 OUT shared_blks_hit int8,
 OUT shared_blks_read int8,
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 1eac9edaee..73d82a632d 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -78,9 +78,11 @@
 #include "storage/ipc.h"
 #include "storage/spin.h"
 #include "tcop/utility.h"
+#include "tcop/pquery.h"
 #include "utils/acl.h"
 #include "utils/builtins.h"
 #include "utils/memutils.h"
+#include "utils/plancache.h"
 
 PG_MODULE_MAGIC;
 
@@ -138,6 +140,8 @@ typedef enum pgssStoreKind
 	 */
 	PGSS_PLAN = 0,
 	PGSS_EXEC,
+	PGSS_EXEC_GENERAL,
+	PGSS_EXEC_CUSTOM,
 
 	PGSS_NUMKIND/* Must be last value of this enum */
 } pgssStoreKind;
@@ -258,6 +262,13 @@ typedef struct pgssJumbleState
 	int			highest_extern_param_id;
 } pgssJumbleState;
 
+typedef enum pgssPlanType
+{
+	PGSS_PLAN_TYPE_NONE,
+	PGSS_PLAN_TYPE_GENERIC,
+	PGSS_PLAN_TYPE_CUSTOM,
+} pgssPlanType;
+
 /* Local variables */
 
 /* Current nesting depth of ExecutorRun+ProcessUtility calls */
@@ -266,6 +277,9 @@ static int	exec_nested_level = 0;
 /* Current nesting depth of planner calls */
 static int	plan_nested_level = 0;
 
+/* Current plan type */
+static pgssPlanType	plantype = PGSS_PLAN_TYPE_NONE;
+
 /* Saved hook values in case of unload */
 static shmem_startup_hook_type prev_shmem_startup_hook = NULL;
 static post_parse_analyze_hook_type prev_post_parse_analyze_hook = NULL;
@@ -1013,6 +1027,20 @@ pgss_ExecutorStart(QueryDesc 

Re: Is it useful to record whether plans are generic or custom?

2020-09-16 Thread Michael Paquier
On Fri, Jul 31, 2020 at 06:47:48PM +0900, torikoshia wrote:
> Oops, sorry about that.
> I just fixed it there for now.

The regression tests of the patch look unstable, and the CF bot is
reporting a failure here:
https://travis-ci.org/github/postgresql-cfbot/postgresql/builds/727833416
--
Michael


signature.asc
Description: PGP signature


RE: Is it useful to record whether plans are generic or custom?

2020-08-17 Thread legrand legrand

 I thought it might be preferable to make a GUC to enable
 or disable this feature, but changing the hash key makes
 it harder.
>>
>>> What happens if the server was running with this option enabled and then
>>> restarted with the option disabled? Firstly two entries for the same query
>>> were stored in pgss because the option was enabled. But when it's disabled
>>> and the server is restarted, those two entries should be merged into one
>>> at the startup of server? If so, that's problematic because it may take
>>> a long time.
>>
>> What would you think about a third value for this flag to handle disabled
>> case (no need to merge entries in this situation) ?
>
> Sorry I failed to understand your point. You mean that we can have another 
> flag
> to specify whether to merge the entries for the same query at that case or 
> not?
>
> If those entries are not merged, what does pg_stat_statements return?
> It returns the sum of those entries? Or either generic or custom entry is
> returned?

The idea is to use a plan_type enum with 'generic','custom','unknown' or 
'unset'.
if tracking plan_type is disabled, then plan_type='unknown',
else plan_type can take 'generic' or 'custom' value.

I'm not proposing to merge results for plan_type when disabling or enabling its 
tracking.


>>> Therefore I think that it's better and simple to just expose the number of
>>> times generic/custom plan was chosen for each query.
>>
>> I thought this feature was mainly needed to identifiy "under optimal generic
>> plans". Without differentiating execution counters, this will be simpler but
>> useless in this case ... isn't it ?

> Could you elaborate "under optimal generic plans"? Sorry, I failed to
> understand your point.. But maybe you're thinking to use this feature to
> check which generic or custom plan is better for each query?

> I was just thinking that this feature was useful to detect the case where
> the query was executed with unpected plan mode. That is, we can detect
> the unexpected case where the query that should be executed with generic
> plan is actually executed with custom plan, and vice versa.

There are many exemples in pg lists, where users comes saying that sometimes
their query takes a (very) longer time than before, without understand why.
I some of some exemples, it is that there is a switch from custom to generic 
after
n executions, and it takes a longer time because generic plan is not as good as
custom one (I call them under optimal generic plans). If pgss keeps counters
aggregated for both plan_types, I don't see how this (under optimal) can be 
shown.
If there is a line in pgss for custom and an other for generic, then it would 
be easier
to compare.

Does this makes sence ?

Regards
PAscal

> Regards,
> --
> Fujii Masao
> Advanced Computing Technology Center
> Research and Development Headquarters
> NTT DATA CORPORATION


Re: Is it useful to record whether plans are generic or custom?

2020-08-17 Thread Fujii Masao




On 2020/07/30 16:34, legrand legrand wrote:

 >> Main purpose is to decide (1) the user interface and (2) the

way to get the plan type from pg_stat_statements.

(1) the user interface
I added a new boolean column 'generic_plan' to both
pg_stat_statements view and the member of the hash key of
pg_stat_statements.

This is because as Legrand pointed out the feature seems
useful under the condition of differentiating all the
counters for a queryid using a generic plan and the one
using a custom one.



I don't like this because this may double the number of entries in pgss.
Which means that the number of entries can more easily reach
pg_stat_statements.max and some entries will be discarded.


Not all the entries will be doubled, only the ones that are prepared.
And even if auto prepare was implemented, having 5000, 1 or 2
max entries seems not a problem to me.


I thought it might be preferable to make a GUC to enable
or disable this feature, but changing the hash key makes
it harder.



What happens if the server was running with this option enabled and then
restarted with the option disabled? Firstly two entries for the same query
were stored in pgss because the option was enabled. But when it's disabled
and the server is restarted, those two entries should be merged into one
at the startup of server? If so, that's problematic because it may take
a long time.


What would you think about a third value for this flag to handle disabled
case (no need to merge entries in this situation) ?


Sorry I failed to understand your point. You mean that we can have another flag
to specify whether to merge the entries for the same query at that case or not?

If those entries are not merged, what does pg_stat_statements return?
It returns the sum of those entries? Or either generic or custom entry is
returned?





Therefore I think that it's better and simple to just expose the number of
times generic/custom plan was chosen for each query.


I thought this feature was mainly needed to identifiy "under optimal generic
plans". Without differentiating execution counters, this will be simpler but
useless in this case ... isn't it ?


Could you elaborate "under optimal generic plans"? Sorry, I failed to
understand your point.. But maybe you're thinking to use this feature to
check which generic or custom plan is better for each query?

I was just thinking that this feature was useful to detect the case where
the query was executed with unpected plan mode. That is, we can detect
the unexpected case where the query that should be executed with generic
plan is actually executed with custom plan, and vice versa.

Regards,

--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION




Re: Is it useful to record whether plans are generic or custom?

2020-07-31 Thread torikoshia

On 2020-07-30 14:31, Fujii Masao wrote:

On 2020/07/22 16:49, torikoshia wrote:

On 2020-07-20 13:57, torikoshia wrote:

As I proposed earlier in this thread, I'm now trying to add 
information

about generic/cudstom plan to pg_stat_statements.
I'll share the idea and the poc patch soon.


Attached a poc patch.


Thanks for the POC patch!

With the patch, when I ran "CREATE EXTENSION pg_stat_statements",
I got the following error.

ERROR:  function pg_stat_statements_reset(oid, oid, bigint) does not 
exist


Oops, sorry about that.
I just fixed it there for now.



Main purpose is to decide (1) the user interface and (2) the
way to get the plan type from pg_stat_statements.

(1) the user interface
I added a new boolean column 'generic_plan' to both
pg_stat_statements view and the member of the hash key of
pg_stat_statements.

This is because as Legrand pointed out the feature seems
useful under the condition of differentiating all the
counters for a queryid using a generic plan and the one
using a custom one.


I don't like this because this may double the number of entries in 
pgss.

Which means that the number of entries can more easily reach
pg_stat_statements.max and some entries will be discarded.



I thought it might be preferable to make a GUC to enable
or disable this feature, but changing the hash key makes
it harder.


What happens if the server was running with this option enabled and 
then
restarted with the option disabled? Firstly two entries for the same 
query
were stored in pgss because the option was enabled. But when it's 
disabled
and the server is restarted, those two entries should be merged into 
one

at the startup of server? If so, that's problematic because it may take
a long time.

Therefore I think that it's better and simple to just expose the number 
of

times generic/custom plan was chosen for each query.

Regards,


Regards,

--
Atsushi Torikoshi
NTT DATA CORPORATIONFrom 793eafad8e988b6754c9d89e0ea14b64b07eef81 Mon Sep 17 00:00:00 2001
From: Atsushi Torikoshi
Date: Fri, 31 Jul 2020 17:52:14 +0900
Subject: [PATCH] Previously the number of custom and generic plans are
 recoreded only in pg_prepared_statements, meaning we could only track them
 regarding current session. This patch records them in pg_stat_statements and
 it enables to track them regarding all sessions of the PostgreSQL instance.

---
 .../pg_stat_statements--1.6--1.7.sql  |  5 ++-
 .../pg_stat_statements--1.7--1.8.sql  |  1 +
 .../pg_stat_statements/pg_stat_statements.c   | 44 +++
 src/backend/utils/cache/plancache.c   |  2 +
 src/include/utils/plancache.h |  1 +
 5 files changed, 42 insertions(+), 11 deletions(-)

diff --git a/contrib/pg_stat_statements/pg_stat_statements--1.6--1.7.sql b/contrib/pg_stat_statements/pg_stat_statements--1.6--1.7.sql
index 6fc3fed4c9..fd7aa05c92 100644
--- a/contrib/pg_stat_statements/pg_stat_statements--1.6--1.7.sql
+++ b/contrib/pg_stat_statements/pg_stat_statements--1.6--1.7.sql
@@ -12,11 +12,12 @@ DROP FUNCTION pg_stat_statements_reset();
 /* Now redefine */
 CREATE FUNCTION pg_stat_statements_reset(IN userid Oid DEFAULT 0,
 	IN dbid Oid DEFAULT 0,
-	IN queryid bigint DEFAULT 0
+	IN queryid bigint DEFAULT 0,
+	IN generic_plan int DEFAULT -1
 )
 RETURNS void
 AS 'MODULE_PATHNAME', 'pg_stat_statements_reset_1_7'
 LANGUAGE C STRICT PARALLEL SAFE;
 
 -- Don't want this to be available to non-superusers.
-REVOKE ALL ON FUNCTION pg_stat_statements_reset(Oid, Oid, bigint) FROM PUBLIC;
+REVOKE ALL ON FUNCTION pg_stat_statements_reset(Oid, Oid, bigint, int) FROM PUBLIC;
diff --git a/contrib/pg_stat_statements/pg_stat_statements--1.7--1.8.sql b/contrib/pg_stat_statements/pg_stat_statements--1.7--1.8.sql
index 0f63f08f7e..0d7c4e7343 100644
--- a/contrib/pg_stat_statements/pg_stat_statements--1.7--1.8.sql
+++ b/contrib/pg_stat_statements/pg_stat_statements--1.7--1.8.sql
@@ -15,6 +15,7 @@ DROP FUNCTION pg_stat_statements(boolean);
 CREATE FUNCTION pg_stat_statements(IN showtext boolean,
 OUT userid oid,
 OUT dbid oid,
+OUT generic_plan bool,
 OUT queryid bigint,
 OUT query text,
 OUT plans int8,
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 6b91c62c31..14c580a95e 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -78,9 +78,11 @@
 #include "storage/ipc.h"
 #include "storage/spin.h"
 #include "tcop/utility.h"
+#include "tcop/pquery.h"
 #include "utils/acl.h"
 #include "utils/builtins.h"
 #include "utils/memutils.h"
+#include "utils/plancache.h"
 
 PG_MODULE_MAGIC;
 
@@ -156,6 +158,7 @@ typedef struct pgssHashKey
 	Oid			userid;			/* user OID */
 	Oid			dbid;			/* database OID */
 	uint64		queryid;		/* query identifier */
+	bool			is_generic_plan;
 } pgssHashKey;
 
 /*
@@ -266,6 +269,9 @@ static int	exec_nested_level = 0;
 /* Current nesting depth of planner calls */
 static 

RE: Is it useful to record whether plans are generic or custom?

2020-07-30 Thread legrand legrand
>> Main purpose is to decide (1) the user interface and (2) the
>> way to get the plan type from pg_stat_statements.
>>
>> (1) the user interface
>> I added a new boolean column 'generic_plan' to both
>> pg_stat_statements view and the member of the hash key of
>> pg_stat_statements.
>>
>> This is because as Legrand pointed out the feature seems
>> useful under the condition of differentiating all the
>> counters for a queryid using a generic plan and the one
>> using a custom one.

> I don't like this because this may double the number of entries in pgss.
> Which means that the number of entries can more easily reach
> pg_stat_statements.max and some entries will be discarded.

Not all the entries will be doubled, only the ones that are prepared.
And even if auto prepare was implemented, having 5000, 1 or 2
max entries seems not a problem to me.

>> I thought it might be preferable to make a GUC to enable
>> or disable this feature, but changing the hash key makes
>> it harder.

> What happens if the server was running with this option enabled and then
> restarted with the option disabled? Firstly two entries for the same query
> were stored in pgss because the option was enabled. But when it's disabled
> and the server is restarted, those two entries should be merged into one
> at the startup of server? If so, that's problematic because it may take
> a long time.

What would you think about a third value for this flag to handle disabled
case (no need to merge entries in this situation) ?

> Therefore I think that it's better and simple to just expose the number of
> times generic/custom plan was chosen for each query.

I thought this feature was mainly needed to identifiy "under optimal generic
plans". Without differentiating execution counters, this will be simpler but
useless in this case ... isn't it ?

> Regards,

> --
> Fujii Masao
> Advanced Computing Technology Center
> Research and Development Headquarters
> NTT DATA CORPORATION

Regards
PAscal


Re: Is it useful to record whether plans are generic or custom?

2020-07-29 Thread Fujii Masao




On 2020/07/22 16:49, torikoshia wrote:

On 2020-07-20 13:57, torikoshia wrote:


As I proposed earlier in this thread, I'm now trying to add information
about generic/cudstom plan to pg_stat_statements.
I'll share the idea and the poc patch soon.


Attached a poc patch.


Thanks for the POC patch!

With the patch, when I ran "CREATE EXTENSION pg_stat_statements",
I got the following error.

ERROR:  function pg_stat_statements_reset(oid, oid, bigint) does not exist




Main purpose is to decide (1) the user interface and (2) the
way to get the plan type from pg_stat_statements.

(1) the user interface
I added a new boolean column 'generic_plan' to both
pg_stat_statements view and the member of the hash key of
pg_stat_statements.

This is because as Legrand pointed out the feature seems
useful under the condition of differentiating all the
counters for a queryid using a generic plan and the one
using a custom one.


I don't like this because this may double the number of entries in pgss.
Which means that the number of entries can more easily reach
pg_stat_statements.max and some entries will be discarded.

 

I thought it might be preferable to make a GUC to enable
or disable this feature, but changing the hash key makes
it harder.


What happens if the server was running with this option enabled and then
restarted with the option disabled? Firstly two entries for the same query
were stored in pgss because the option was enabled. But when it's disabled
and the server is restarted, those two entries should be merged into one
at the startup of server? If so, that's problematic because it may take
a long time.

Therefore I think that it's better and simple to just expose the number of
times generic/custom plan was chosen for each query.

Regards,

--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION




Re: Is it useful to record whether plans are generic or custom?

2020-07-22 Thread torikoshia

On 2020-07-20 13:57, torikoshia wrote:


As I proposed earlier in this thread, I'm now trying to add information
about generic/cudstom plan to pg_stat_statements.
I'll share the idea and the poc patch soon.


Attached a poc patch.

Main purpose is to decide (1) the user interface and (2) the
way to get the plan type from pg_stat_statements.

(1) the user interface
I added a new boolean column 'generic_plan' to both
pg_stat_statements view and the member of the hash key of
pg_stat_statements.

This is because as Legrand pointed out the feature seems
useful under the condition of differentiating all the
counters for a queryid using a generic plan and the one
using a custom one.

I thought it might be preferable to make a GUC to enable
or disable this feature, but changing the hash key makes
it harder.

(2) way to get the plan type from pg_stat_statements
To know whether the plan is generic or not, I added a
member to CachedPlan and get it in the ExecutorStart_hook
from ActivePortal.
I wished to do it in the ExecutorEnd_hook, but the
ActivePortal is not available on executorEnd, so I keep
it on a global variable newly defined in pg_stat_statements.


Any thoughts?

This is a poc patch and I'm going to do below things later:

- update pg_stat_statements version
- change default value for the newly added parameter in
  pg_stat_statements_reset() from -1 to 0(since default for
  other parameters are all 0)
- add regression tests and update docs



Regards,

--
Atsushi Torikoshi
NTT DATA CORPORATIONFrom 793eafad8e988b6754c9d89e0ea14b64b07eef81 Mon Sep 17 00:00:00 2001
From: Atsushi Torikoshi
Date: Wed, 22 Jul 2020 16:00:04 +0900
Subject: [PATCH] [poc] Previously the number of custom and generic plans are
 recoreded only in pg_prepared_statements, meaning we could only track them
 regarding current session. This patch records them in pg_stat_statements and
 it enables to track them regarding all sessions of the PostgreSQL instance.

---
 .../pg_stat_statements--1.6--1.7.sql  |  3 +-
 .../pg_stat_statements--1.7--1.8.sql  |  1 +
 .../pg_stat_statements/pg_stat_statements.c   | 44 +++
 src/backend/utils/cache/plancache.c   |  2 +
 src/include/utils/plancache.h |  1 +
 5 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/contrib/pg_stat_statements/pg_stat_statements--1.6--1.7.sql b/contrib/pg_stat_statements/pg_stat_statements--1.6--1.7.sql
index 6fc3fed4c9..5ab0a26b77 100644
--- a/contrib/pg_stat_statements/pg_stat_statements--1.6--1.7.sql
+++ b/contrib/pg_stat_statements/pg_stat_statements--1.6--1.7.sql
@@ -12,7 +12,8 @@ DROP FUNCTION pg_stat_statements_reset();
 /* Now redefine */
 CREATE FUNCTION pg_stat_statements_reset(IN userid Oid DEFAULT 0,
 	IN dbid Oid DEFAULT 0,
-	IN queryid bigint DEFAULT 0
+	IN queryid bigint DEFAULT 0,
+	IN generic_plan int DEFAULT -1
 )
 RETURNS void
 AS 'MODULE_PATHNAME', 'pg_stat_statements_reset_1_7'
diff --git a/contrib/pg_stat_statements/pg_stat_statements--1.7--1.8.sql b/contrib/pg_stat_statements/pg_stat_statements--1.7--1.8.sql
index 0f63f08f7e..0d7c4e7343 100644
--- a/contrib/pg_stat_statements/pg_stat_statements--1.7--1.8.sql
+++ b/contrib/pg_stat_statements/pg_stat_statements--1.7--1.8.sql
@@ -15,6 +15,7 @@ DROP FUNCTION pg_stat_statements(boolean);
 CREATE FUNCTION pg_stat_statements(IN showtext boolean,
 OUT userid oid,
 OUT dbid oid,
+OUT generic_plan bool,
 OUT queryid bigint,
 OUT query text,
 OUT plans int8,
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 14cad19afb..5d74dc04cd 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -78,9 +78,11 @@
 #include "storage/ipc.h"
 #include "storage/spin.h"
 #include "tcop/utility.h"
+#include "tcop/pquery.h"
 #include "utils/acl.h"
 #include "utils/builtins.h"
 #include "utils/memutils.h"
+#include "utils/plancache.h"
 
 PG_MODULE_MAGIC;
 
@@ -156,6 +158,7 @@ typedef struct pgssHashKey
 	Oid			userid;			/* user OID */
 	Oid			dbid;			/* database OID */
 	uint64		queryid;		/* query identifier */
+	bool			is_generic_plan;
 } pgssHashKey;
 
 /*
@@ -266,6 +269,9 @@ static int	exec_nested_level = 0;
 /* Current nesting depth of planner calls */
 static int	plan_nested_level = 0;
 
+/* Current plan type */
+static bool	is_generic_plan = false;
+
 /* Saved hook values in case of unload */
 static shmem_startup_hook_type prev_shmem_startup_hook = NULL;
 static post_parse_analyze_hook_type prev_post_parse_analyze_hook = NULL;
@@ -367,7 +373,7 @@ static char *qtext_fetch(Size query_offset, int query_len,
 		 char *buffer, Size buffer_size);
 static bool need_gc_qtexts(void);
 static void gc_qtexts(void);
-static void entry_reset(Oid userid, Oid dbid, uint64 queryid);
+static void entry_reset(Oid userid, Oid dbid, uint64 queryid, int generic_plan);
 static void AppendJumble(pgssJumbleState *jstate,
 		 

Re: Is it useful to record whether plans are generic or custom?

2020-07-19 Thread torikoshia

On 2020-07-20 11:57, Fujii Masao wrote:

On 2020/07/17 16:25, Fujii Masao wrote:



On 2020/07/16 11:50, torikoshia wrote:

On 2020-07-15 11:44, Fujii Masao wrote:

On 2020/07/14 21:24, torikoshia wrote:

On 2020-07-10 10:49, torikoshia wrote:

On 2020-07-08 16:41, Fujii Masao wrote:

On 2020/07/08 10:14, torikoshia wrote:

On 2020-07-06 22:16, Fujii Masao wrote:

On 2020/06/11 14:59, torikoshia wrote:

On 2020-06-10 18:00, Kyotaro Horiguchi wrote:



+    TupleDescInitEntry(tupdesc, (AttrNumber) 8, "last_plan",

This could be a problem if we showed the last plan in this 
view. I

think "last_plan_type" would be better.

+    if (prep_stmt->plansource->last_plan_type == 
PLAN_CACHE_TYPE_CUSTOM)

+    values[7] = CStringGetTextDatum("custom");
+    else if (prep_stmt->plansource->last_plan_type 
== PLAN_CACHE_TYPE_GENERIC)

+    values[7] = CStringGetTextDatum("generic");
+    else
+    nulls[7] = true;

Using swith-case prevents future additional type (if any) 
from being

unhandled.  I think we are recommending that as a convension.


Thanks for your reviewing!

I've attached a patch that reflects your comments.


Thanks for the patch! Here are the comments.


Thanks for your review!


+    Number of times generic plan was choosen
+    Number of times custom plan was choosen

Typo: "choosen" should be "chosen"?


Thanks, fixed them.

+  role="column_definition">
+   last_plan_type 
text

+  
+  
+    Tells the last plan type was generic or custom. If the 
prepared

+    statement has not executed yet, this field is null
+  

Could you tell me how this information is expected to be used?
I think that generic_plans and custom_plans are useful when 
investigating
the cause of performance drop by cached plan mode. But I failed 
to get

how much useful last_plan_type is.


This may be an exceptional case, but I once had a case needed
to ensure whether generic or custom plan was chosen for specific
queries in a development environment.


In your case, probably you had to ensure that the last multiple 
(or every)
executions chose generic or custom plan? If yes, I'm afraid that 
displaying

only the last plan mode is not enough for your case. No?
So it seems better to check generic_plans or custom_plans columns 
in the

view rather than last_plan_type even in your case. Thought?


Yeah, I now feel last_plan is not so necessary and only the 
numbers of

generic/custom plan is enough.

If there are no objections, I'm going to remove this column and 
related codes.


As mentioned, I removed last_plan column.


Thanks for updating the patch! It basically looks good to me.

I have one comment; you added the regression tests for generic and
custom plans into prepare.sql. But the similar tests already exist 
in
plancache.sql. So isn't it better to add the tests for generic_plans 
and

custom_plans columns, into plancache.sql?



Thanks for your comments!

Agreed.
I removed tests on prepare.sql and added them to plancache.sql.
Thoughts?


Thanks for updating the patch!
I also applied the following minor changes to the patch.

-    Number of times generic plan was chosen
+   Number of times generic plan was chosen
-    Number of times custom plan was chosen
+   Number of times custom plan was chosen

I got rid of one space character before those descriptions because
they should start from the position of 7th character.

  -- but we can force a custom plan
  set plan_cache_mode to force_custom_plan;
  explain (costs off) execute test_mode_pp(2);
+select name, generic_plans, custom_plans from pg_prepared_statements
+  where  name = 'test_mode_pp';

In the regression test, I added the execution of 
pg_prepared_statements
after the last execution of test query, to confirm that custom plan is 
used
when force_custom_plan is set, by checking from 
pg_prepared_statements.


I changed the status of this patch to "Ready for Committer" in CF.

Barring any objection, I will commit this patch.


Committed. Thanks!


Thanks!

As I proposed earlier in this thread, I'm now trying to add information
about generic/cudstom plan to pg_stat_statements.
I'll share the idea and the poc patch soon.

Regards,

--
Atsushi Torikoshi
NTT DATA CORPORATION




Re: Is it useful to record whether plans are generic or custom?

2020-07-19 Thread Fujii Masao




On 2020/07/17 16:25, Fujii Masao wrote:



On 2020/07/16 11:50, torikoshia wrote:

On 2020-07-15 11:44, Fujii Masao wrote:

On 2020/07/14 21:24, torikoshia wrote:

On 2020-07-10 10:49, torikoshia wrote:

On 2020-07-08 16:41, Fujii Masao wrote:

On 2020/07/08 10:14, torikoshia wrote:

On 2020-07-06 22:16, Fujii Masao wrote:

On 2020/06/11 14:59, torikoshia wrote:

On 2020-06-10 18:00, Kyotaro Horiguchi wrote:



+    TupleDescInitEntry(tupdesc, (AttrNumber) 8, "last_plan",

This could be a problem if we showed the last plan in this view. I
think "last_plan_type" would be better.

+    if (prep_stmt->plansource->last_plan_type == 
PLAN_CACHE_TYPE_CUSTOM)
+    values[7] = CStringGetTextDatum("custom");
+    else if (prep_stmt->plansource->last_plan_type == 
PLAN_CACHE_TYPE_GENERIC)
+    values[7] = CStringGetTextDatum("generic");
+    else
+    nulls[7] = true;

Using swith-case prevents future additional type (if any) from being
unhandled.  I think we are recommending that as a convension.


Thanks for your reviewing!

I've attached a patch that reflects your comments.


Thanks for the patch! Here are the comments.


Thanks for your review!


+    Number of times generic plan was choosen
+    Number of times custom plan was choosen

Typo: "choosen" should be "chosen"?


Thanks, fixed them.


+  
+   last_plan_type text
+  
+  
+    Tells the last plan type was generic or custom. If the prepared
+    statement has not executed yet, this field is null
+  

Could you tell me how this information is expected to be used?
I think that generic_plans and custom_plans are useful when investigating
the cause of performance drop by cached plan mode. But I failed to get
how much useful last_plan_type is.


This may be an exceptional case, but I once had a case needed
to ensure whether generic or custom plan was chosen for specific
queries in a development environment.


In your case, probably you had to ensure that the last multiple (or every)
executions chose generic or custom plan? If yes, I'm afraid that displaying
only the last plan mode is not enough for your case. No?
So it seems better to check generic_plans or custom_plans columns in the
view rather than last_plan_type even in your case. Thought?


Yeah, I now feel last_plan is not so necessary and only the numbers of
generic/custom plan is enough.

If there are no objections, I'm going to remove this column and related codes.


As mentioned, I removed last_plan column.


Thanks for updating the patch! It basically looks good to me.

I have one comment; you added the regression tests for generic and
custom plans into prepare.sql. But the similar tests already exist in
plancache.sql. So isn't it better to add the tests for generic_plans and
custom_plans columns, into plancache.sql?



Thanks for your comments!

Agreed.
I removed tests on prepare.sql and added them to plancache.sql.
Thoughts?


Thanks for updating the patch!
I also applied the following minor changes to the patch.

-    Number of times generic plan was chosen
+   Number of times generic plan was chosen
-    Number of times custom plan was chosen
+   Number of times custom plan was chosen

I got rid of one space character before those descriptions because
they should start from the position of 7th character.

  -- but we can force a custom plan
  set plan_cache_mode to force_custom_plan;
  explain (costs off) execute test_mode_pp(2);
+select name, generic_plans, custom_plans from pg_prepared_statements
+  where  name = 'test_mode_pp';

In the regression test, I added the execution of pg_prepared_statements
after the last execution of test query, to confirm that custom plan is used
when force_custom_plan is set, by checking from pg_prepared_statements.

I changed the status of this patch to "Ready for Committer" in CF.

Barring any objection, I will commit this patch.


Committed. Thanks!

Regards,

--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION




Re: Is it useful to record whether plans are generic or custom?

2020-07-17 Thread Fujii Masao



On 2020/07/16 11:50, torikoshia wrote:

On 2020-07-15 11:44, Fujii Masao wrote:

On 2020/07/14 21:24, torikoshia wrote:

On 2020-07-10 10:49, torikoshia wrote:

On 2020-07-08 16:41, Fujii Masao wrote:

On 2020/07/08 10:14, torikoshia wrote:

On 2020-07-06 22:16, Fujii Masao wrote:

On 2020/06/11 14:59, torikoshia wrote:

On 2020-06-10 18:00, Kyotaro Horiguchi wrote:



+    TupleDescInitEntry(tupdesc, (AttrNumber) 8, "last_plan",

This could be a problem if we showed the last plan in this view. I
think "last_plan_type" would be better.

+    if (prep_stmt->plansource->last_plan_type == 
PLAN_CACHE_TYPE_CUSTOM)
+    values[7] = CStringGetTextDatum("custom");
+    else if (prep_stmt->plansource->last_plan_type == 
PLAN_CACHE_TYPE_GENERIC)
+    values[7] = CStringGetTextDatum("generic");
+    else
+    nulls[7] = true;

Using swith-case prevents future additional type (if any) from being
unhandled.  I think we are recommending that as a convension.


Thanks for your reviewing!

I've attached a patch that reflects your comments.


Thanks for the patch! Here are the comments.


Thanks for your review!


+    Number of times generic plan was choosen
+    Number of times custom plan was choosen

Typo: "choosen" should be "chosen"?


Thanks, fixed them.


+  
+   last_plan_type text
+  
+  
+    Tells the last plan type was generic or custom. If the prepared
+    statement has not executed yet, this field is null
+  

Could you tell me how this information is expected to be used?
I think that generic_plans and custom_plans are useful when investigating
the cause of performance drop by cached plan mode. But I failed to get
how much useful last_plan_type is.


This may be an exceptional case, but I once had a case needed
to ensure whether generic or custom plan was chosen for specific
queries in a development environment.


In your case, probably you had to ensure that the last multiple (or every)
executions chose generic or custom plan? If yes, I'm afraid that displaying
only the last plan mode is not enough for your case. No?
So it seems better to check generic_plans or custom_plans columns in the
view rather than last_plan_type even in your case. Thought?


Yeah, I now feel last_plan is not so necessary and only the numbers of
generic/custom plan is enough.

If there are no objections, I'm going to remove this column and related codes.


As mentioned, I removed last_plan column.


Thanks for updating the patch! It basically looks good to me.

I have one comment; you added the regression tests for generic and
custom plans into prepare.sql. But the similar tests already exist in
plancache.sql. So isn't it better to add the tests for generic_plans and
custom_plans columns, into plancache.sql?



Thanks for your comments!

Agreed.
I removed tests on prepare.sql and added them to plancache.sql.
Thoughts?


Thanks for updating the patch!
I also applied the following minor changes to the patch.

-Number of times generic plan was chosen
+   Number of times generic plan was chosen
-Number of times custom plan was chosen
+   Number of times custom plan was chosen

I got rid of one space character before those descriptions because
they should start from the position of 7th character.

 -- but we can force a custom plan
 set plan_cache_mode to force_custom_plan;
 explain (costs off) execute test_mode_pp(2);
+select name, generic_plans, custom_plans from pg_prepared_statements
+  where  name = 'test_mode_pp';

In the regression test, I added the execution of pg_prepared_statements
after the last execution of test query, to confirm that custom plan is used
when force_custom_plan is set, by checking from pg_prepared_statements.

I changed the status of this patch to "Ready for Committer" in CF.

Barring any objection, I will commit this patch.

Regards,

--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index e9cdff4864..de69487bec 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -10830,6 +10830,24 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts 
ppx
frontend/backend protocol
   
  
+
+ 
+  
+   generic_plans int8
+  
+  
+   Number of times generic plan was chosen
+  
+ 
+
+ 
+  
+   custom_plans int8
+  
+  
+   Number of times custom plan was chosen
+  
+ 
 

   
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index 80d6df8ac1..4b18be5b27 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -694,7 +694,8 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause 
*into, ExplainState *es,
 
 /*
  * This set returning function reads all the prepared statements and
- * returns a set of (name, 

Re: Is it useful to record whether plans are generic or custom?

2020-07-15 Thread torikoshia

On 2020-07-15 11:44, Fujii Masao wrote:

On 2020/07/14 21:24, torikoshia wrote:

On 2020-07-10 10:49, torikoshia wrote:

On 2020-07-08 16:41, Fujii Masao wrote:

On 2020/07/08 10:14, torikoshia wrote:

On 2020-07-06 22:16, Fujii Masao wrote:

On 2020/06/11 14:59, torikoshia wrote:

On 2020-06-10 18:00, Kyotaro Horiguchi wrote:



+    TupleDescInitEntry(tupdesc, (AttrNumber) 8, "last_plan",

This could be a problem if we showed the last plan in this view. 
I

think "last_plan_type" would be better.

+    if (prep_stmt->plansource->last_plan_type == 
PLAN_CACHE_TYPE_CUSTOM)

+    values[7] = CStringGetTextDatum("custom");
+    else if (prep_stmt->plansource->last_plan_type == 
PLAN_CACHE_TYPE_GENERIC)

+    values[7] = CStringGetTextDatum("generic");
+    else
+    nulls[7] = true;

Using swith-case prevents future additional type (if any) from 
being

unhandled.  I think we are recommending that as a convension.


Thanks for your reviewing!

I've attached a patch that reflects your comments.


Thanks for the patch! Here are the comments.


Thanks for your review!


+    Number of times generic plan was choosen
+    Number of times custom plan was choosen

Typo: "choosen" should be "chosen"?


Thanks, fixed them.

+  role="column_definition">
+   last_plan_type 
text

+  
+  
+    Tells the last plan type was generic or custom. If the 
prepared

+    statement has not executed yet, this field is null
+  

Could you tell me how this information is expected to be used?
I think that generic_plans and custom_plans are useful when 
investigating
the cause of performance drop by cached plan mode. But I failed to 
get

how much useful last_plan_type is.


This may be an exceptional case, but I once had a case needed
to ensure whether generic or custom plan was chosen for specific
queries in a development environment.


In your case, probably you had to ensure that the last multiple (or 
every)
executions chose generic or custom plan? If yes, I'm afraid that 
displaying

only the last plan mode is not enough for your case. No?
So it seems better to check generic_plans or custom_plans columns in 
the

view rather than last_plan_type even in your case. Thought?


Yeah, I now feel last_plan is not so necessary and only the numbers 
of

generic/custom plan is enough.

If there are no objections, I'm going to remove this column and 
related codes.


As mentioned, I removed last_plan column.


Thanks for updating the patch! It basically looks good to me.

I have one comment; you added the regression tests for generic and
custom plans into prepare.sql. But the similar tests already exist in
plancache.sql. So isn't it better to add the tests for generic_plans 
and

custom_plans columns, into plancache.sql?



Thanks for your comments!

Agreed.
I removed tests on prepare.sql and added them to plancache.sql.
Thoughts?


Regards,


--
Atsushi Torikoshi
NTT DATA CORPORATIONFrom e3517479cea76e88f3ab8626d14452b36288dcb5 Mon Sep 17 00:00:00 2001
From: Atsushi Torikoshi 
Date: Tue, 14 Jul 2020 10:27:32 +0900
Subject: [PATCH] We didn't have an easy way to find how many times generic and
 ustom plans of a prepared statement have been executed. This patch exposes
 the numbers of both plans in pg_prepared_statements.

---
 doc/src/sgml/catalogs.sgml  | 18 
 src/backend/commands/prepare.c  | 15 +++---
 src/backend/utils/cache/plancache.c | 17 
 src/include/catalog/pg_proc.dat |  6 ++--
 src/include/utils/plancache.h   |  3 +-
 src/test/regress/expected/plancache.out | 37 -
 src/test/regress/expected/rules.out |  6 ++--
 src/test/regress/sql/plancache.sql  | 12 +++-
 8 files changed, 96 insertions(+), 18 deletions(-)

diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index e9cdff4864..8bc6d685f4 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -10830,6 +10830,24 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
frontend/backend protocol
   
  
+
+ 
+  
+   generic_plans int8
+  
+  
+Number of times generic plan was chosen
+  
+ 
+
+ 
+  
+   custom_plans int8
+  
+  
+Number of times custom plan was chosen
+  
+ 
 

   
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index 80d6df8ac1..4b18be5b27 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -694,7 +694,8 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into, ExplainState *es,
 
 /*
  * This set returning function reads all the prepared statements and
- * returns a set of (name, statement, prepare_time, param_types, from_sql).
+ * returns a set of (name, statement, prepare_time, param_types, from_sql,
+ * generic_plans, custom_plans).
  */
 Datum
 

Re: Is it useful to record whether plans are generic or custom?

2020-07-14 Thread Fujii Masao




On 2020/07/14 21:24, torikoshia wrote:

On 2020-07-10 10:49, torikoshia wrote:

On 2020-07-08 16:41, Fujii Masao wrote:

On 2020/07/08 10:14, torikoshia wrote:

On 2020-07-06 22:16, Fujii Masao wrote:

On 2020/06/11 14:59, torikoshia wrote:

On 2020-06-10 18:00, Kyotaro Horiguchi wrote:



+    TupleDescInitEntry(tupdesc, (AttrNumber) 8, "last_plan",

This could be a problem if we showed the last plan in this view. I
think "last_plan_type" would be better.

+    if (prep_stmt->plansource->last_plan_type == 
PLAN_CACHE_TYPE_CUSTOM)
+    values[7] = CStringGetTextDatum("custom");
+    else if (prep_stmt->plansource->last_plan_type == 
PLAN_CACHE_TYPE_GENERIC)
+    values[7] = CStringGetTextDatum("generic");
+    else
+    nulls[7] = true;

Using swith-case prevents future additional type (if any) from being
unhandled.  I think we are recommending that as a convension.


Thanks for your reviewing!

I've attached a patch that reflects your comments.


Thanks for the patch! Here are the comments.


Thanks for your review!


+    Number of times generic plan was choosen
+    Number of times custom plan was choosen

Typo: "choosen" should be "chosen"?


Thanks, fixed them.


+  
+   last_plan_type text
+  
+  
+    Tells the last plan type was generic or custom. If the prepared
+    statement has not executed yet, this field is null
+  

Could you tell me how this information is expected to be used?
I think that generic_plans and custom_plans are useful when investigating
the cause of performance drop by cached plan mode. But I failed to get
how much useful last_plan_type is.


This may be an exceptional case, but I once had a case needed
to ensure whether generic or custom plan was chosen for specific
queries in a development environment.


In your case, probably you had to ensure that the last multiple (or every)
executions chose generic or custom plan? If yes, I'm afraid that displaying
only the last plan mode is not enough for your case. No?
So it seems better to check generic_plans or custom_plans columns in the
view rather than last_plan_type even in your case. Thought?


Yeah, I now feel last_plan is not so necessary and only the numbers of
generic/custom plan is enough.

If there are no objections, I'm going to remove this column and related codes.


As mentioned, I removed last_plan column.


Thanks for updating the patch! It basically looks good to me.

I have one comment; you added the regression tests for generic and
custom plans into prepare.sql. But the similar tests already exist in
plancache.sql. So isn't it better to add the tests for generic_plans and
custom_plans columns, into plancache.sql?

Regards,


--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION




Re: Is it useful to record whether plans are generic or custom?

2020-07-14 Thread torikoshia

On 2020-07-10 10:49, torikoshia wrote:

On 2020-07-08 16:41, Fujii Masao wrote:

On 2020/07/08 10:14, torikoshia wrote:

On 2020-07-06 22:16, Fujii Masao wrote:

On 2020/06/11 14:59, torikoshia wrote:

On 2020-06-10 18:00, Kyotaro Horiguchi wrote:



+    TupleDescInitEntry(tupdesc, (AttrNumber) 8, "last_plan",

This could be a problem if we showed the last plan in this view.  
I

think "last_plan_type" would be better.

+    if (prep_stmt->plansource->last_plan_type == 
PLAN_CACHE_TYPE_CUSTOM)

+    values[7] = CStringGetTextDatum("custom");
+    else if (prep_stmt->plansource->last_plan_type == 
PLAN_CACHE_TYPE_GENERIC)

+    values[7] = CStringGetTextDatum("generic");
+    else
+    nulls[7] = true;

Using swith-case prevents future additional type (if any) from 
being

unhandled.  I think we are recommending that as a convension.


Thanks for your reviewing!

I've attached a patch that reflects your comments.


Thanks for the patch! Here are the comments.


Thanks for your review!


+    Number of times generic plan was choosen
+    Number of times custom plan was choosen

Typo: "choosen" should be "chosen"?


Thanks, fixed them.

+  role="column_definition">

+   last_plan_type text
+  
+  
+    Tells the last plan type was generic or custom. If the 
prepared

+    statement has not executed yet, this field is null
+  

Could you tell me how this information is expected to be used?
I think that generic_plans and custom_plans are useful when 
investigating
the cause of performance drop by cached plan mode. But I failed to 
get

how much useful last_plan_type is.


This may be an exceptional case, but I once had a case needed
to ensure whether generic or custom plan was chosen for specific
queries in a development environment.


In your case, probably you had to ensure that the last multiple (or 
every)
executions chose generic or custom plan? If yes, I'm afraid that 
displaying

only the last plan mode is not enough for your case. No?
So it seems better to check generic_plans or custom_plans columns in 
the

view rather than last_plan_type even in your case. Thought?


Yeah, I now feel last_plan is not so necessary and only the numbers of
generic/custom plan is enough.

If there are no objections, I'm going to remove this column and related 
codes.


As mentioned, I removed last_plan column.


Regards,

--
Atsushi Torikoshi
NTT DATA CORPORATIONFrom e417fc58d51ab0c06de34a563d580c7d4017a1db Mon Sep 17 00:00:00 2001
From: Atsushi Torikoshi 
Date: Tue, 14 Jul 2020 20:57:16 +0900
Subject: [PATCH] We didn't have an easy way to find how many times generic and
 custom plans of a prepared statement have been executed. This patch exposes
 the numbers of both plans in pg_prepared_statements.

---
 doc/src/sgml/catalogs.sgml| 18 ++
 src/backend/commands/prepare.c| 15 +---
 src/backend/utils/cache/plancache.c   | 17 +
 src/include/catalog/pg_proc.dat   |  6 ++--
 src/include/utils/plancache.h |  3 +-
 src/test/regress/expected/prepare.out | 51 +++
 src/test/regress/expected/rules.out   |  6 ++--
 src/test/regress/sql/prepare.sql  | 15 
 8 files changed, 115 insertions(+), 16 deletions(-)

diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index e9cdff4864..8bc6d685f4 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -10830,6 +10830,24 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
frontend/backend protocol
   
  
+
+ 
+  
+   generic_plans int8
+  
+  
+Number of times generic plan was chosen
+  
+ 
+
+ 
+  
+   custom_plans int8
+  
+  
+Number of times custom plan was chosen
+  
+ 
 

   
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index 80d6df8ac1..4b18be5b27 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -694,7 +694,8 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into, ExplainState *es,
 
 /*
  * This set returning function reads all the prepared statements and
- * returns a set of (name, statement, prepare_time, param_types, from_sql).
+ * returns a set of (name, statement, prepare_time, param_types, from_sql,
+ * generic_plans, custom_plans).
  */
 Datum
 pg_prepared_statement(PG_FUNCTION_ARGS)
@@ -723,7 +724,7 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
 	 * build tupdesc for result tuples. This must match the definition of the
 	 * pg_prepared_statements view in system_views.sql
 	 */
-	tupdesc = CreateTemplateTupleDesc(5);
+	tupdesc = CreateTemplateTupleDesc(7);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
 	   TEXTOID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "statement",
@@ -734,6 +735,10 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
 	   REGTYPEARRAYOID, -1, 0);
 	

Re: Is it useful to record whether plans are generic or custom?

2020-07-09 Thread torikoshia

On 2020-07-08 16:41, Fujii Masao wrote:

On 2020/07/08 10:14, torikoshia wrote:

On 2020-07-06 22:16, Fujii Masao wrote:

On 2020/06/11 14:59, torikoshia wrote:

On 2020-06-10 18:00, Kyotaro Horiguchi wrote:



+    TupleDescInitEntry(tupdesc, (AttrNumber) 8, "last_plan",

This could be a problem if we showed the last plan in this view.  I
think "last_plan_type" would be better.

+    if (prep_stmt->plansource->last_plan_type == 
PLAN_CACHE_TYPE_CUSTOM)

+    values[7] = CStringGetTextDatum("custom");
+    else if (prep_stmt->plansource->last_plan_type == 
PLAN_CACHE_TYPE_GENERIC)

+    values[7] = CStringGetTextDatum("generic");
+    else
+    nulls[7] = true;

Using swith-case prevents future additional type (if any) from 
being

unhandled.  I think we are recommending that as a convension.


Thanks for your reviewing!

I've attached a patch that reflects your comments.


Thanks for the patch! Here are the comments.


Thanks for your review!


+    Number of times generic plan was choosen
+    Number of times custom plan was choosen

Typo: "choosen" should be "chosen"?


Thanks, fixed them.

+  role="column_definition">

+   last_plan_type text
+  
+  
+    Tells the last plan type was generic or custom. If the 
prepared

+    statement has not executed yet, this field is null
+  

Could you tell me how this information is expected to be used?
I think that generic_plans and custom_plans are useful when 
investigating
the cause of performance drop by cached plan mode. But I failed to 
get

how much useful last_plan_type is.


This may be an exceptional case, but I once had a case needed
to ensure whether generic or custom plan was chosen for specific
queries in a development environment.


In your case, probably you had to ensure that the last multiple (or 
every)
executions chose generic or custom plan? If yes, I'm afraid that 
displaying

only the last plan mode is not enough for your case. No?
So it seems better to check generic_plans or custom_plans columns in 
the

view rather than last_plan_type even in your case. Thought?


Yeah, I now feel last_plan is not so necessary and only the numbers of
generic/custom plan is enough.

If there are no objections, I'm going to remove this column and related 
codes.



Regards,

--
Atsushi Torikoshi
NTT DATA CORPORATION




Re: Is it useful to record whether plans are generic or custom?

2020-07-08 Thread Fujii Masao




On 2020/07/08 10:14, torikoshia wrote:

On 2020-07-06 22:16, Fujii Masao wrote:

On 2020/06/11 14:59, torikoshia wrote:

On 2020-06-10 18:00, Kyotaro Horiguchi wrote:



+    TupleDescInitEntry(tupdesc, (AttrNumber) 8, "last_plan",

This could be a problem if we showed the last plan in this view.  I
think "last_plan_type" would be better.

+    if (prep_stmt->plansource->last_plan_type == 
PLAN_CACHE_TYPE_CUSTOM)
+    values[7] = CStringGetTextDatum("custom");
+    else if (prep_stmt->plansource->last_plan_type == 
PLAN_CACHE_TYPE_GENERIC)
+    values[7] = CStringGetTextDatum("generic");
+    else
+    nulls[7] = true;

Using swith-case prevents future additional type (if any) from being
unhandled.  I think we are recommending that as a convension.


Thanks for your reviewing!

I've attached a patch that reflects your comments.


Thanks for the patch! Here are the comments.


Thanks for your review!


+    Number of times generic plan was choosen
+    Number of times custom plan was choosen

Typo: "choosen" should be "chosen"?


Thanks, fixed them.


+  
+   last_plan_type text
+  
+  
+    Tells the last plan type was generic or custom. If the prepared
+    statement has not executed yet, this field is null
+  

Could you tell me how this information is expected to be used?
I think that generic_plans and custom_plans are useful when investigating
the cause of performance drop by cached plan mode. But I failed to get
how much useful last_plan_type is.


This may be an exceptional case, but I once had a case needed
to ensure whether generic or custom plan was chosen for specific
queries in a development environment.


In your case, probably you had to ensure that the last multiple (or every)
executions chose generic or custom plan? If yes, I'm afraid that displaying
only the last plan mode is not enough for your case. No?
So it seems better to check generic_plans or custom_plans columns in the
view rather than last_plan_type even in your case. Thought?

Regards,

--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION




Re: Is it useful to record whether plans are generic or custom?

2020-07-07 Thread torikoshia

On 2020-07-06 22:16, Fujii Masao wrote:

On 2020/06/11 14:59, torikoshia wrote:

On 2020-06-10 18:00, Kyotaro Horiguchi wrote:



+    TupleDescInitEntry(tupdesc, (AttrNumber) 8, "last_plan",

This could be a problem if we showed the last plan in this view.  I
think "last_plan_type" would be better.

+    if (prep_stmt->plansource->last_plan_type == 
PLAN_CACHE_TYPE_CUSTOM)

+    values[7] = CStringGetTextDatum("custom");
+    else if (prep_stmt->plansource->last_plan_type == 
PLAN_CACHE_TYPE_GENERIC)

+    values[7] = CStringGetTextDatum("generic");
+    else
+    nulls[7] = true;

Using swith-case prevents future additional type (if any) from being
unhandled.  I think we are recommending that as a convension.


Thanks for your reviewing!

I've attached a patch that reflects your comments.


Thanks for the patch! Here are the comments.


Thanks for your review!


+Number of times generic plan was choosen
+Number of times custom plan was choosen

Typo: "choosen" should be "chosen"?


Thanks, fixed them.

+  role="column_definition">

+   last_plan_type text
+  
+  
+Tells the last plan type was generic or custom. If the 
prepared

+statement has not executed yet, this field is null
+  

Could you tell me how this information is expected to be used?
I think that generic_plans and custom_plans are useful when 
investigating

the cause of performance drop by cached plan mode. But I failed to get
how much useful last_plan_type is.


This may be an exceptional case, but I once had a case needed
to ensure whether generic or custom plan was chosen for specific
queries in a development environment.

Of course, we can know it from adding EXPLAIN and ensuring whether $n
is contained in the plan, but I feel using the view is easier to use
and understand.


Regards,

--
Atsushi Torikoshi
NTT DATA CORPORATIONFrom f2155b1a9f3b500eca490827dd044f5c0f704dd3 Mon Sep 17 00:00:00 2001
From: Atsushi Torikoshi
Date: Wed, 8 Jul 2020 09:17:22 +0900
Subject: [PATCH] We didn't have an easy way to find how many times generic or
 custom plans of a prepared statement have been executed.  This patch exposes
 such numbers of both plans and the last plan type in pg_prepared_statements.
From 08183ee7ef827761f1ed38d2ab62b4f8f748baca Mon Sep 17 00:00:00 2001
---
 doc/src/sgml/catalogs.sgml| 28 +++
 src/backend/commands/prepare.c| 29 ---
 src/backend/utils/cache/plancache.c   | 23 
 src/include/catalog/pg_proc.dat   |  6 ++--
 src/include/utils/plancache.h | 12 ++-
 src/test/regress/expected/prepare.out | 51 +++
 src/test/regress/expected/rules.out   |  7 ++--
 src/test/regress/sql/prepare.sql  | 15 
 8 files changed, 155 insertions(+), 16 deletions(-)

diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 003d278370..146dc2208b 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -10829,6 +10829,34 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
frontend/backend protocol
   
  
+
+ 
+  
+   generic_plans bigint
+  
+  
+Number of times generic plan was chosen
+  
+ 
+
+ 
+  
+   custom_plans bigint
+  
+  
+Number of times custom plan was chosen
+  
+ 
+
+ 
+  
+   last_plan_type text
+  
+  
+Tells the last plan type was generic or custom. If the prepared
+statement has not executed yet, this field is null
+  
+ 
 

   
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index 80d6df8ac1..b4b1865d48 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -694,7 +694,8 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into, ExplainState *es,
 
 /*
  * This set returning function reads all the prepared statements and
- * returns a set of (name, statement, prepare_time, param_types, from_sql).
+ * returns a set of (name, statement, prepare_time, param_types, from_sql,
+ * generic_plans, custom_plans, last_plan_type).
  */
 Datum
 pg_prepared_statement(PG_FUNCTION_ARGS)
@@ -723,7 +724,7 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
 	 * build tupdesc for result tuples. This must match the definition of the
 	 * pg_prepared_statements view in system_views.sql
 	 */
-	tupdesc = CreateTemplateTupleDesc(5);
+	tupdesc = CreateTemplateTupleDesc(8);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
 	   TEXTOID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "statement",
@@ -734,6 +735,12 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
 	   REGTYPEARRAYOID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 5, "from_sql",
 	   BOOLOID, -1, 0);
+	TupleDescInitEntry(tupdesc, (AttrNumber) 6, "generic_plans",
+	   INT8OID, -1, 0);
+	TupleDescInitEntry(tupdesc, 

Re: Is it useful to record whether plans are generic or custom?

2020-07-06 Thread Fujii Masao




On 2020/06/11 14:59, torikoshia wrote:

On 2020-06-10 18:00, Kyotaro Horiguchi wrote:



+    TupleDescInitEntry(tupdesc, (AttrNumber) 8, "last_plan",

This could be a problem if we showed the last plan in this view.  I
think "last_plan_type" would be better.

+    if (prep_stmt->plansource->last_plan_type == 
PLAN_CACHE_TYPE_CUSTOM)
+    values[7] = CStringGetTextDatum("custom");
+    else if (prep_stmt->plansource->last_plan_type == 
PLAN_CACHE_TYPE_GENERIC)
+    values[7] = CStringGetTextDatum("generic");
+    else
+    nulls[7] = true;

Using swith-case prevents future additional type (if any) from being
unhandled.  I think we are recommending that as a convension.


Thanks for your reviewing!

I've attached a patch that reflects your comments.


Thanks for the patch! Here are the comments.


+Number of times generic plan was choosen
+Number of times custom plan was choosen

Typo: "choosen" should be "chosen"?


+  
+   last_plan_type text
+  
+  
+Tells the last plan type was generic or custom. If the prepared
+statement has not executed yet, this field is null
+  

Could you tell me how this information is expected to be used?
I think that generic_plans and custom_plans are useful when investigating
the cause of performance drop by cached plan mode. But I failed to get
how much useful last_plan_type is.


Regards,

--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION




Re: Is it useful to record whether plans are generic or custom?

2020-06-11 Thread torikoshia

On 2020-06-10 18:00, Kyotaro Horiguchi wrote:



+   TupleDescInitEntry(tupdesc, (AttrNumber) 8, "last_plan",

This could be a problem if we showed the last plan in this view.  I
think "last_plan_type" would be better.

+			if (prep_stmt->plansource->last_plan_type == 
PLAN_CACHE_TYPE_CUSTOM)

+   values[7] = CStringGetTextDatum("custom");
+			else if (prep_stmt->plansource->last_plan_type == 
PLAN_CACHE_TYPE_GENERIC)

+   values[7] = CStringGetTextDatum("generic");
+   else
+   nulls[7] = true;

Using swith-case prevents future additional type (if any) from being
unhandled.  I think we are recommending that as a convension.


Thanks for your reviewing!

I've attached a patch that reflects your comments.


Regards,

--
Atsushi TorikoshiFrom f2155b1a9f3b500eca490827dd044f5c0f704dd3 Mon Sep 17 00:00:00 2001
From: Atsushi Torikoshi
Date: Thu, 11 Jun 2020 11:35:25 +0900
Subject: [PATCH] We didn't have an easy way to find how many times generic or
 custom plans of a prepared statement have been executed.  This patch exposes
 such numbers of both plans and the last plan type in pg_prepared_statements.

fixed comments
---
 doc/src/sgml/catalogs.sgml| 28 +++
 src/backend/commands/prepare.c| 29 ---
 src/backend/utils/cache/plancache.c   | 23 
 src/include/catalog/pg_proc.dat   |  6 ++--
 src/include/utils/plancache.h | 12 ++-
 src/test/regress/expected/prepare.out | 51 +++
 src/test/regress/expected/rules.out   |  7 ++--
 src/test/regress/sql/prepare.sql  | 15 
 8 files changed, 155 insertions(+), 16 deletions(-)

diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 700271fd40..ac9e56d5b3 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -10829,6 +10829,34 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
frontend/backend protocol
   
  
+
+ 
+  
+   generic_plans bigint
+  
+  
+Number of times generic plan was choosen
+  
+ 
+
+ 
+  
+   custom_plans bigint
+  
+  
+Number of times custom plan was choosen
+  
+ 
+
+ 
+  
+   last_plan_type text
+  
+  
+Tells the last plan type was generic or custom. If the prepared
+statement has not executed yet, this field is null
+  
+ 
 

   
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index 80d6df8ac1..b4b1865d48 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -694,7 +694,8 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into, ExplainState *es,
 
 /*
  * This set returning function reads all the prepared statements and
- * returns a set of (name, statement, prepare_time, param_types, from_sql).
+ * returns a set of (name, statement, prepare_time, param_types, from_sql,
+ * generic_plans, custom_plans, last_plan_type).
  */
 Datum
 pg_prepared_statement(PG_FUNCTION_ARGS)
@@ -723,7 +724,7 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
 	 * build tupdesc for result tuples. This must match the definition of the
 	 * pg_prepared_statements view in system_views.sql
 	 */
-	tupdesc = CreateTemplateTupleDesc(5);
+	tupdesc = CreateTemplateTupleDesc(8);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
 	   TEXTOID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "statement",
@@ -734,6 +735,12 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
 	   REGTYPEARRAYOID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 5, "from_sql",
 	   BOOLOID, -1, 0);
+	TupleDescInitEntry(tupdesc, (AttrNumber) 6, "generic_plans",
+	   INT8OID, -1, 0);
+	TupleDescInitEntry(tupdesc, (AttrNumber) 7, "custom_plans",
+	   INT8OID, -1, 0);
+	TupleDescInitEntry(tupdesc, (AttrNumber) 8, "last_plan_type",
+	   TEXTOID, -1, 0);
 
 	/*
 	 * We put all the tuples into a tuplestore in one scan of the hashtable.
@@ -755,8 +762,8 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
 		hash_seq_init(_seq, prepared_queries);
 		while ((prep_stmt = hash_seq_search(_seq)) != NULL)
 		{
-			Datum		values[5];
-			bool		nulls[5];
+			Datum		values[8];
+			bool		nulls[8];
 
 			MemSet(nulls, 0, sizeof(nulls));
 
@@ -766,6 +773,20 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
 			values[3] = build_regtype_array(prep_stmt->plansource->param_types,
 			prep_stmt->plansource->num_params);
 			values[4] = BoolGetDatum(prep_stmt->from_sql);
+			values[5] = Int64GetDatumFast(prep_stmt->plansource->num_generic_plans);
+			values[6] = Int64GetDatumFast(prep_stmt->plansource->num_custom_plans);
+
+			switch (prep_stmt->plansource->last_plan_type)
+			{
+case PLAN_CACHE_TYPE_CUSTOM:
+	values[7] = CStringGetTextDatum("custom");
+	break;
+case PLAN_CACHE_TYPE_GENERIC:
+	values[7] = CStringGetTextDatum("generic");

Re: Is it useful to record whether plans are generic or custom?

2020-06-10 Thread Kyotaro Horiguchi
At Wed, 10 Jun 2020 10:50:58 +0900, torikoshia  
wrote in 
> On 2020-06-08 20:45, Masahiro Ikeda wrote:
> 
> > BTW, I found that the dependency between function's comments and
> > the modified code is broken at latest patch. Before this is
> > committed, please fix it.
> > ```
> > diff --git a/src/backend/commands/prepare.c
> > b/src/backend/commands/prepare.c
> > index 990782e77f..b63d3214df 100644
> > --- a/src/backend/commands/prepare.c
> > +++ b/src/backend/commands/prepare.c
> > @@ -694,7 +694,8 @@ ExplainExecuteQuery(ExecuteStmt *execstmt,
> > IntoClause *into, ExplainState *es,
> >  /*
> >   * This set returning function reads all the prepared statements and
> > - * returns a set of (name, statement, prepare_time, param_types,
> > - * from_sql).
> > + * returns a set of (name, statement, prepare_time, param_types,
> > from_sql,
> > + * generic_plans, custom_plans, last_plan).
> >   */
> >  Datum
> >  pg_prepared_statement(PG_FUNCTION_ARGS)
> > ```
> 
> Thanks for reviewing!
> 
> I've fixed it.

+   TupleDescInitEntry(tupdesc, (AttrNumber) 8, "last_plan",

This could be a problem if we showed the last plan in this view.  I
think "last_plan_type" would be better.

+   if (prep_stmt->plansource->last_plan_type == 
PLAN_CACHE_TYPE_CUSTOM)
+   values[7] = CStringGetTextDatum("custom");
+   else if (prep_stmt->plansource->last_plan_type == 
PLAN_CACHE_TYPE_GENERIC)
+   values[7] = CStringGetTextDatum("generic");
+   else
+   nulls[7] = true;

Using swith-case prevents future additional type (if any) from being
unhandled.  I think we are recommending that as a convension.

regards.

-- 
Kyotaro Horiguchi
NTT Open Source Software Center




Re: Is it useful to record whether plans are generic or custom?

2020-06-09 Thread torikoshia

On 2020-06-08 20:45, Masahiro Ikeda wrote:


BTW, I found that the dependency between function's comments and
the modified code is broken at latest patch. Before this is
committed, please fix it.

```
diff --git a/src/backend/commands/prepare.c 
b/src/backend/commands/prepare.c

index 990782e77f..b63d3214df 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -694,7 +694,8 @@ ExplainExecuteQuery(ExecuteStmt *execstmt,
IntoClause *into, ExplainState *es,

 /*
  * This set returning function reads all the prepared statements and
- * returns a set of (name, statement, prepare_time, param_types, 
from_sql).
+ * returns a set of (name, statement, prepare_time, param_types, 
from_sql,

+ * generic_plans, custom_plans, last_plan).
  */
 Datum
 pg_prepared_statement(PG_FUNCTION_ARGS)
```


Thanks for reviewing!

I've fixed it.



Regards,

--
Atsushi TorikoshiFrom f2155b1a9f3b500eca490827dd044f5c0f704dd3 Mon Sep 17 00:00:00 2001
From: Atsushi Torikoshi
Date: Tue, 10 Jun 2020 10:22:20 +0900
Subject: [PATCH] We didn't have an easy way to find how many times generic or
 custom plans of a prepared statement have been executed.  This patch exposes
 such numbers of both plans and the last plan type in pg_prepared_statements.

---
 doc/src/sgml/catalogs.sgml| 28 +++
 src/backend/commands/prepare.c| 24 ++---
 src/backend/utils/cache/plancache.c   | 23 
 src/include/catalog/pg_proc.dat   |  6 ++--
 src/include/utils/plancache.h | 12 ++-
 src/test/regress/expected/prepare.out | 51 +++
 src/test/regress/expected/rules.out   |  7 ++--
 src/test/regress/sql/prepare.sql  | 15 
 8 files changed, 150 insertions(+), 16 deletions(-)

diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 700271fd40..9e96a5518e 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -10829,6 +10829,34 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
frontend/backend protocol
   
  
+
+ 
+  
+   generic_plans bigint
+  
+  
+Number of times generic plan was choosen
+  
+ 
+
+ 
+  
+   custom_plans bigint
+  
+  
+Number of times custom plan was choosen
+  
+ 
+
+ 
+  
+   last_plan text
+  
+  
+Tells the last plan was generic or custom. If the prepared
+statement has not executed yet, this field is null
+  
+ 
 

   
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index 80d6df8ac1..d60cf6f67a 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -694,7 +694,8 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into, ExplainState *es,
 
 /*
  * This set returning function reads all the prepared statements and
- * returns a set of (name, statement, prepare_time, param_types, from_sql).
+ * returns a set of (name, statement, prepare_time, param_types, from_sql,
+ * generic_plans, custom_plans, last_plan).
  */
 Datum
 pg_prepared_statement(PG_FUNCTION_ARGS)
@@ -723,7 +724,7 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
 	 * build tupdesc for result tuples. This must match the definition of the
 	 * pg_prepared_statements view in system_views.sql
 	 */
-	tupdesc = CreateTemplateTupleDesc(5);
+	tupdesc = CreateTemplateTupleDesc(8);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
 	   TEXTOID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "statement",
@@ -734,6 +735,12 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
 	   REGTYPEARRAYOID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 5, "from_sql",
 	   BOOLOID, -1, 0);
+	TupleDescInitEntry(tupdesc, (AttrNumber) 6, "generic_plans",
+	   INT8OID, -1, 0);
+	TupleDescInitEntry(tupdesc, (AttrNumber) 7, "custom_plans",
+	   INT8OID, -1, 0);
+	TupleDescInitEntry(tupdesc, (AttrNumber) 8, "last_plan",
+	   TEXTOID, -1, 0);
 
 	/*
 	 * We put all the tuples into a tuplestore in one scan of the hashtable.
@@ -755,8 +762,8 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
 		hash_seq_init(_seq, prepared_queries);
 		while ((prep_stmt = hash_seq_search(_seq)) != NULL)
 		{
-			Datum		values[5];
-			bool		nulls[5];
+			Datum		values[8];
+			bool		nulls[8];
 
 			MemSet(nulls, 0, sizeof(nulls));
 
@@ -766,6 +773,15 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
 			values[3] = build_regtype_array(prep_stmt->plansource->param_types,
 			prep_stmt->plansource->num_params);
 			values[4] = BoolGetDatum(prep_stmt->from_sql);
+			values[5] = Int64GetDatumFast(prep_stmt->plansource->num_generic_plans);
+			values[6] = Int64GetDatumFast(prep_stmt->plansource->num_custom_plans);
+
+			if (prep_stmt->plansource->last_plan_type == PLAN_CACHE_TYPE_CUSTOM)
+values[7] = CStringGetTextDatum("custom");
+			else if (prep_stmt->plansource->last_plan_type == PLAN_CACHE_TYPE_GENERIC)
+values[7] = 

Re: Is it useful to record whether plans are generic or custom?

2020-06-08 Thread Masahiro Ikeda

On 2020-06-04 17:04, Atsushi Torikoshi wrote:

On Mon, May 25, 2020 at 10:54 AM Atsushi Torikoshi 
wrote:


On Thu, May 21, 2020 at 5:10 PM Kyotaro Horiguchi
 wrote:


Cost numbers would look better if it is cooked a bit.  Is it worth
being in core?


I didn't come up with ideas about how to use them.
IMHO they might not so necessary..



Perhaps plan_generation is not needed there.


+1.
Now 'calls' is sufficient and 'plan_generation' may confuse users.

BTW, considering 'calls' in pg_stat_statements is the number of
times
statements were EXECUTED and 'plans' is the number of times
statements were PLANNED,  how about substituting 'calls' for
'plans'?


I've modified the above points and also exposed the numbers of each
 generic plans and custom plans.

I'm now a little bit worried about the below change which removed
the overflow checking for num_custom_plans, which was introduced
in 0001-Expose-counters-of-plancache-to-pg_prepared_statement.patch,
but I've left it because the maximum of int64 seems enough large
for counters.
Also referencing other counters in pg_stat_user_tables, they don't
seem to care about it.

```
-   /* Accumulate total costs of custom plans, but 'ware
overflow */
-   if (plansource->num_custom_plans < INT_MAX)
-   {
-   plansource->total_custom_cost +=
cached_plan_cost(plan, true);
-   plansource->num_custom_plans++;
-   }

```

Regards,

Atsushi Torikoshi





As a user, I think this feature is useful for performance analysis.
I hope that this feature is merged.

BTW, I found that the dependency between function's comments and
the modified code is broken at latest patch. Before this is
committed, please fix it.

```
diff --git a/src/backend/commands/prepare.c 
b/src/backend/commands/prepare.c

index 990782e77f..b63d3214df 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -694,7 +694,8 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, 
IntoClause *into, ExplainState *es,


 /*
  * This set returning function reads all the prepared statements and
- * returns a set of (name, statement, prepare_time, param_types, 
from_sql).
+ * returns a set of (name, statement, prepare_time, param_types, 
from_sql,

+ * generic_plans, custom_plans, last_plan).
  */
 Datum
 pg_prepared_statement(PG_FUNCTION_ARGS)
```

Regards,

--
Masahiro Ikeda




Re: Is it useful to record whether plans are generic or custom?

2020-06-04 Thread Atsushi Torikoshi
On Mon, May 25, 2020 at 10:54 AM Atsushi Torikoshi  wrote:

> On Thu, May 21, 2020 at 5:10 PM Kyotaro Horiguchi 
> wrote:
>
>> Cost numbers would look better if it is cooked a bit.  Is it worth
>> being in core?
>
>
> I didn't come up with ideas about how to use them.
> IMHO they might not so necessary..
>


> Perhaps plan_generation is not needed there.
>>
>
> +1.
> Now 'calls' is sufficient and 'plan_generation' may confuse users.
>
> BTW, considering 'calls' in pg_stat_statements is the number of times
> statements were EXECUTED and 'plans' is the number of times
> statements were PLANNED,  how about substituting 'calls' for 'plans'?
>

I've modified the above points and also exposed the numbers of each
 generic plans and custom plans.

I'm now a little bit worried about the below change which removed
the overflow checking for num_custom_plans, which was introduced
in 0001-Expose-counters-of-plancache-to-pg_prepared_statement.patch,
but I've left it because the maximum of int64 seems enough large
for counters.
Also referencing other counters in pg_stat_user_tables, they don't
seem to care about it.

```
-   /* Accumulate total costs of custom plans, but 'ware
overflow */
-   if (plansource->num_custom_plans < INT_MAX)
-   {
-   plansource->total_custom_cost +=
cached_plan_cost(plan, true);
-   plansource->num_custom_plans++;
-   }
```

Regards,

Atsushi Torikoshi

>


0003-Expose-counters-of-plancache-to-pg_prepared_statement.patch
Description: Binary data


Re: Is it useful to record whether plans are generic or custom?

2020-05-24 Thread Atsushi Torikoshi
Thanks for writing a patch!

On Thu, May 21, 2020 at 5:10 PM Kyotaro Horiguchi 
wrote:

> At Thu, 21 May 2020 12:18:16 +0900, Fujii Masao <
> masao.fu...@oss.nttdata.com> wrote in
> > I like the idea exposing more CachedPlanSource fields in
> > pg_prepared_statements. I agree it's useful, e.g., for the debug
> > purpose.
> > This is why I implemented the similar feature in my extension.
> > Please see [1] for details.
>
> Thanks. I'm not sure plan_cache_mode should be a part of the view.
> Cost numbers would look better if it is cooked a bit.  Is it worth
> being in core?


I didn't come up with ideas about how to use them.
IMHO they might not so necessary..


> =# select * from pg_prepared_statements;
> -[ RECORD 1 ]---+
> name| p1
> statement   | prepare p1 as select a from t where a = $1;
> prepare_time| 2020-05-21 15:41:50.419578+09
> parameter_types | {integer}
> from_sql| t
> calls   | 7
> custom_calls| 5
> plan_generation | 6
> generic_cost| 4.3105
> custom_cost | 9.31
>
> Perhaps plan_generation is not needed there.
>

+1.
Now 'calls' is sufficient and 'plan_generation' may confuse users.

BTW, considering 'calls' in pg_stat_statements is the number of times
statements were EXECUTED and 'plans' is the number of times
statements were PLANNED,  how about substituting 'calls' for 'plans'?


At Tue, 19 May 2020 22:56:17 +0900, Atsushi Torikoshi 
> wrote in
> > Instead, I'm now considering using a static hash for prepared queries
> > (static HTAB *prepared_queries).
>
> That might be complex and fragile considering nested query and SPI
> calls.  I'm not sure, but could we use ActivePortal?
> ActivePortal->cplan is a CachedPlan, which can hold the generic/custom
> information.
>

Yes, I once looked for hooks which can get Portal, I couldn't find them.
And it also seems difficult getting keys for HTAB *prepared_queries
in existing executor hooks.
There may be oversights, but I'm now feeling returning to the idea
hook additions.

| Portal includes CachedPlanSource but there seem no hooks to
| take Portal.
| So I'm wondering it's necessary to add a hook to get Portal
| or CachedPlanSource.
| Are these too much change for getting plan types?


On Thu, May 21, 2020 at 5:43 PM Tatsuro Yamada <
tatsuro.yamada...@nttcom.co.jp> wrote:

> I tried to creating PoC patch too, so I share it.
> Please find attached file.
>

Thanks!

I agree with your idea showing the latest plan is generic or custom.

This patch judges whether the lastest plan was generic based on
plansource->gplan existence,  but plansource->gplan can exist even
when the planner chooses custom.
For example, a prepared statement was executed first 6 times and
a generic plan was generated for comparison but the custom plan
won.

Attached another patch showing latest plan based on
'0001-Expose-counters-of-plancache-to-pg_prepared_statemen.patch'.

As I wrote above, I suppose some of the columns might not necessary
and it'd better change some column and variable names, but  I left them
for other opinions.

Regards,

--
Atsushi Torikoshi


0002-Expose-counters-of-plancache-to-pg_prepared_statement.patch
Description: Binary data


Re: Is it useful to record whether plans are generic or custom?

2020-05-21 Thread Tatsuro Yamada

Hi Torikoshi-san!

On 2020/05/21 17:10, Kyotaro Horiguchi wrote:

At Thu, 21 May 2020 12:18:16 +0900, Fujii Masao  
wrote in



On 2020/05/20 21:56, Atsushi Torikoshi wrote:

On Wed, May 20, 2020 at 1:32 PM Kyotaro Horiguchi
mailto:horikyota@gmail.com>> wrote:
 At Tue, 19 May 2020 22:56:17 +0900, Atsushi Torikoshi
 mailto:ato...@gmail.com>> wrote in
  > On Sat, May 16, 2020 at 6:01 PM legrand legrand
  > mailto:legrand_legr...@hotmail.com>>
  > wrote:
  >
  > BTW, I'd also appreciate other opinions about recording the number
  > of generic and custom plans on pg_stat_statemtents.
 If you/we just want to know how a prepared statement is executed,
 couldn't we show that information in pg_prepared_statements view?
 =# select * from pg_prepared_statements;
 -[ RECORD 1 ]---+
 name| stmt1
 statement   | prepare stmt1 as select * from t where b = $1;
 prepare_time| 2020-05-20 12:01:55.733469+09
 parameter_types | {text}
 from_sql| t
 exec_custom | 5<- existing num_custom_plans
 exec_total  | 40   <- new member of CachedPlanSource
Thanks, Horiguchi-san!
Adding counters to pg_prepared_statements seems useful when we want
to know the way prepared statements executed in the current session.


I like the idea exposing more CachedPlanSource fields in
pg_prepared_statements. I agree it's useful, e.g., for the debug
purpose.
This is why I implemented the similar feature in my extension.
Please see [1] for details.


Thanks. I'm not sure plan_cache_mode should be a part of the view.
Cost numbers would look better if it is cooked a bit.  Is it worth
being in core?

=# select * from pg_prepared_statements;
-[ RECORD 1 ]---+
name| p1
statement   | prepare p1 as select a from t where a = $1;
prepare_time| 2020-05-21 15:41:50.419578+09
parameter_types | {integer}
from_sql| t
calls   | 7
custom_calls| 5
plan_generation | 6
generic_cost| 4.3105
custom_cost | 9.31

Perhaps plan_generation is not needed there.


I tried to creating PoC patch too, so I share it.
Please find attached file.

# Test case
prepare count as select count(*) from pg_class where oid >$1;
execute count(1); select * from pg_prepared_statements;

-[ RECORD 1 ]---+--
name| count
statement   | prepare count as select count(*) from pg_class where oid >$1;
prepare_time| 2020-05-21 17:41:16.134362+09
parameter_types | {oid}
from_sql| t
is_generic_plan | f <= False

You can see the following result, when you execute it 6 times.

-[ RECORD 1 ]---+--
name| count
statement   | prepare count as select count(*) from pg_class where oid >$1;
prepare_time| 2020-05-21 17:41:16.134362+09
parameter_types | {oid}
from_sql| t
is_generic_plan | t <= True


Thanks,
Tatsuro Yamada
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index 80d6df8ac1..63de4fdb78 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -723,7 +723,7 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
 * build tupdesc for result tuples. This must match the definition of 
the
 * pg_prepared_statements view in system_views.sql
 */
-   tupdesc = CreateTemplateTupleDesc(5);
+   tupdesc = CreateTemplateTupleDesc(6);
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
   TEXTOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "statement",
@@ -734,6 +734,8 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
   REGTYPEARRAYOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 5, "from_sql",
   BOOLOID, -1, 0);
+   TupleDescInitEntry(tupdesc, (AttrNumber) 6, "is_generic_plan",
+  BOOLOID, -1, 0);
 
/*
 * We put all the tuples into a tuplestore in one scan of the hashtable.
@@ -755,8 +757,8 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
hash_seq_init(_seq, prepared_queries);
while ((prep_stmt = hash_seq_search(_seq)) != NULL)
{
-   Datum   values[5];
-   boolnulls[5];
+   Datum   values[6];
+   boolnulls[6];
 
MemSet(nulls, 0, sizeof(nulls));
 
@@ -766,6 +768,7 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
values[3] = 
build_regtype_array(prep_stmt->plansource->param_types,


Re: Is it useful to record whether plans are generic or custom?

2020-05-21 Thread Kyotaro Horiguchi
At Thu, 21 May 2020 12:18:16 +0900, Fujii Masao  
wrote in 
> 
> 
> On 2020/05/20 21:56, Atsushi Torikoshi wrote:
> > On Wed, May 20, 2020 at 1:32 PM Kyotaro Horiguchi
> > mailto:horikyota@gmail.com>> wrote:
> > At Tue, 19 May 2020 22:56:17 +0900, Atsushi Torikoshi
> > mailto:ato...@gmail.com>> wrote in
> >  > On Sat, May 16, 2020 at 6:01 PM legrand legrand
> >  > mailto:legrand_legr...@hotmail.com>>
> >  > wrote:
> >  >
> >  > BTW, I'd also appreciate other opinions about recording the number
> >  > of generic and custom plans on pg_stat_statemtents.
> > If you/we just want to know how a prepared statement is executed,
> > couldn't we show that information in pg_prepared_statements view?
> > =# select * from pg_prepared_statements;
> > -[ RECORD 1 ]---+
> > name            | stmt1
> > statement       | prepare stmt1 as select * from t where b = $1;
> > prepare_time    | 2020-05-20 12:01:55.733469+09
> > parameter_types | {text}
> > from_sql        | t
> > exec_custom     | 5    <- existing num_custom_plans
> > exec_total          | 40   <- new member of CachedPlanSource
> > Thanks, Horiguchi-san!
> > Adding counters to pg_prepared_statements seems useful when we want
> > to know the way prepared statements executed in the current session.
> 
> I like the idea exposing more CachedPlanSource fields in
> pg_prepared_statements. I agree it's useful, e.g., for the debug
> purpose.
> This is why I implemented the similar feature in my extension.
> Please see [1] for details.

Thanks. I'm not sure plan_cache_mode should be a part of the view.
Cost numbers would look better if it is cooked a bit.  Is it worth
being in core?

=# select * from pg_prepared_statements;
-[ RECORD 1 ]---+
name| p1
statement   | prepare p1 as select a from t where a = $1;
prepare_time| 2020-05-21 15:41:50.419578+09
parameter_types | {integer}
from_sql| t
calls   | 7
custom_calls| 5
plan_generation | 6
generic_cost| 4.3105
custom_cost | 9.31

Perhaps plan_generation is not needed there.

> > And I also feel adding counters to pg_stat_statements will be
> > convenient
> > especially in production environments because it enables us to get
> > information about not only the current session but all sessions of a
> > PostgreSQL instance.
> 
> +1

Agreed. It is global and persistent.

At Tue, 19 May 2020 22:56:17 +0900, Atsushi Torikoshi  wrote 
in 
> Instead, I'm now considering using a static hash for prepared queries
> (static HTAB *prepared_queries).

That might be complex and fragile considering nested query and SPI
calls.  I'm not sure, but could we use ActivePortal?
ActivePortal->cplan is a CachedPlan, which can hold the generic/custom
information.

Instead, 


> [1]
> https://github.com/MasaoFujii/pg_cheat_funcs#record-pg_cached_plan_sourcestmt-text

regards.

-- 
Kyotaro Horiguchi
NTT Open Source Software Center
>From 1c6a3dd41a59504244134ee44ddd4516191656da Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi 
Date: Thu, 21 May 2020 15:32:38 +0900
Subject: [PATCH] Expose counters of plancache to pg_prepared_statements

We didn't have an easy way to find how many times generic or custom
plans of a prepared statement have been executed.  This patch exposes
such numbers and costs of both plans in pg_prepared_statements.
---
 doc/src/sgml/catalogs.sgml| 45 +++
 src/backend/commands/prepare.c| 30 --
 src/backend/utils/cache/plancache.c   | 13 
 src/include/catalog/pg_proc.dat   |  6 ++--
 src/include/utils/plancache.h |  5 +--
 src/test/regress/expected/prepare.out | 43 +
 src/test/regress/expected/rules.out   |  9 --
 src/test/regress/sql/prepare.sql  |  9 ++
 8 files changed, 144 insertions(+), 16 deletions(-)

diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index b1b077c97f..950ed30694 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -10826,6 +10826,51 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
frontend/backend protocol
   
  
+
+ 
+  
+   calls bigint
+  
+  
+   Number of times the prepared statement was executed
+  
+ 
+
+ 
+  
+   custom_calls bigint
+  
+  
+   Number of times generic plan is executed for the prepared statement
+  
+ 
+
+ 
+  
+   plan_geneation bigint
+  
+  
+   Number of times execution plan was generated for the prepared statement
+  
+ 
+
+ 
+  
+   generic_cost double precision
+  
+  
+   Estimated cost of generic plan. NULL if not yet planned.
+  
+ 
+
+ 
+  
+   custom_cost double precision
+  
+  
+   Estimated cost of custom plans. 

Re: Is it useful to record whether plans are generic or custom?

2020-05-20 Thread Fujii Masao




On 2020/05/20 21:56, Atsushi Torikoshi wrote:


On Wed, May 20, 2020 at 1:32 PM Kyotaro Horiguchi mailto:horikyota@gmail.com>> wrote:

At Tue, 19 May 2020 22:56:17 +0900, Atsushi Torikoshi mailto:ato...@gmail.com>> wrote in
 > On Sat, May 16, 2020 at 6:01 PM legrand legrand mailto:legrand_legr...@hotmail.com>>
 > wrote:
 >
 > BTW, I'd also appreciate other opinions about recording the number
 > of generic and custom plans on pg_stat_statemtents.

If you/we just want to know how a prepared statement is executed,
couldn't we show that information in pg_prepared_statements view?

=# select * from pg_prepared_statements;
-[ RECORD 1 ]---+
name            | stmt1
statement       | prepare stmt1 as select * from t where b = $1;
prepare_time    | 2020-05-20 12:01:55.733469+09
parameter_types | {text}
from_sql        | t
exec_custom     | 5    <- existing num_custom_plans
exec_total          | 40   <- new member of CachedPlanSource


Thanks, Horiguchi-san!

Adding counters to pg_prepared_statements seems useful when we want
to know the way prepared statements executed in the current session.


I like the idea exposing more CachedPlanSource fields in
pg_prepared_statements. I agree it's useful, e.g., for the debug purpose.
This is why I implemented the similar feature in my extension.
Please see [1] for details.


And I also feel adding counters to pg_stat_statements will be convenient
especially in production environments because it enables us to get
information about not only the current session but all sessions of a
PostgreSQL instance.


+1

Regards,

[1]
https://github.com/MasaoFujii/pg_cheat_funcs#record-pg_cached_plan_sourcestmt-text


--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION




Re: Is it useful to record whether plans are generic or custom?

2020-05-20 Thread Atsushi Torikoshi
On Wed, May 20, 2020 at 1:32 PM Kyotaro Horiguchi 
wrote:

> At Tue, 19 May 2020 22:56:17 +0900, Atsushi Torikoshi 
> wrote in
> > On Sat, May 16, 2020 at 6:01 PM legrand legrand <
> legrand_legr...@hotmail.com>
> > wrote:
> >
> > BTW, I'd also appreciate other opinions about recording the number
> > of generic and custom plans on pg_stat_statemtents.
>
> If you/we just want to know how a prepared statement is executed,
> couldn't we show that information in pg_prepared_statements view?
>
> =# select * from pg_prepared_statements;
> -[ RECORD 1 ]---+
> name| stmt1
> statement   | prepare stmt1 as select * from t where b = $1;
> prepare_time| 2020-05-20 12:01:55.733469+09
> parameter_types | {text}
> from_sql| t
> exec_custom | 5<- existing num_custom_plans
> exec_total  | 40   <- new member of CachedPlanSource
>

Thanks, Horiguchi-san!

Adding counters to pg_prepared_statements seems useful when we want
to know the way prepared statements executed in the current session.

And I also feel adding counters to pg_stat_statements will be convenient
especially in production environments because it enables us to get
information about not only the current session but all sessions of a
PostgreSQL instance.

If both changes are worthwhile, considering implementation complexity,
it may be reasonable to firstly add columns to pg_prepared_statements
and then work on pg_stat_statements.

Regards,

--
Atsushi Torikoshi


Re: Is it useful to record whether plans are generic or custom?

2020-05-19 Thread Kyotaro Horiguchi
At Tue, 19 May 2020 22:56:17 +0900, Atsushi Torikoshi  wrote 
in 
> On Sat, May 16, 2020 at 6:01 PM legrand legrand 
> wrote:
> 
> > > To track executed plan types, I think execution layer hooks
> > > are appropriate.
> > > These hooks, however, take QueryDesc as a param and it does
> > > not include cached plan information.
> >
> > It seems that the same QueryDesc entry is reused when executing
> > a generic plan.
> > For exemple marking queryDesc->plannedstmt->queryId (outside
> > pg_stat_statements) with a pseudo tag during ExecutorStart
> > reappears in later executions with generic plans ...
> >
> > Is this QueryDesc reusable by a custom plan ? If not maybe a solution
> > could be to add a flag in queryDesc->plannedstmt ?
> >
> 
> Thanks for your proposal!
> 
> I first thought it was a good idea and tried to add a flag to QueryDesc,
> but the comments on QueryDesc say it encapsulates everything that
> the executor needs to execute a query.
> 
> Whether a plan is generic or custom is not what executor needs to
> know for running queries, so now I hesitate to do so.
> 
> Instead, I'm now considering using a static hash for prepared queries
> (static HTAB *prepared_queries).
> 
> 
> BTW, I'd also appreciate other opinions about recording the number
> of generic and custom plans on pg_stat_statemtents.

If you/we just want to know how a prepared statement is executed,
couldn't we show that information in pg_prepared_statements view?

=# select * from pg_prepared_statements;
-[ RECORD 1 ]---+
name| stmt1
statement   | prepare stmt1 as select * from t where b = $1;
prepare_time| 2020-05-20 12:01:55.733469+09
parameter_types | {text}
from_sql| t
exec_custom | 5<- existing num_custom_plans
exec_total  | 40   <- new member of CachedPlanSource

regards.

-- 
Kyotaro Horiguchi
NTT Open Source Software Center




Re: Is it useful to record whether plans are generic or custom?

2020-05-19 Thread Atsushi Torikoshi
On Sat, May 16, 2020 at 6:01 PM legrand legrand 
wrote:

> > To track executed plan types, I think execution layer hooks
> > are appropriate.
> > These hooks, however, take QueryDesc as a param and it does
> > not include cached plan information.
>
> It seems that the same QueryDesc entry is reused when executing
> a generic plan.
> For exemple marking queryDesc->plannedstmt->queryId (outside
> pg_stat_statements) with a pseudo tag during ExecutorStart
> reappears in later executions with generic plans ...
>
> Is this QueryDesc reusable by a custom plan ? If not maybe a solution
> could be to add a flag in queryDesc->plannedstmt ?
>

Thanks for your proposal!

I first thought it was a good idea and tried to add a flag to QueryDesc,
but the comments on QueryDesc say it encapsulates everything that
the executor needs to execute a query.

Whether a plan is generic or custom is not what executor needs to
know for running queries, so now I hesitate to do so.

Instead, I'm now considering using a static hash for prepared queries
(static HTAB *prepared_queries).


BTW, I'd also appreciate other opinions about recording the number
of generic and custom plans on pg_stat_statemtents.


Regards,

--
Atsushi Torikoshi


Re: Is it useful to record whether plans are generic or custom?

2020-05-16 Thread legrand legrand
> To track executed plan types, I think execution layer hooks
> are appropriate.
> These hooks, however, take QueryDesc as a param and it does
> not include cached plan information.

It seems that the same QueryDesc entry is reused when executing
a generic plan.
For exemple marking queryDesc->plannedstmt->queryId (outside 
pg_stat_statements) with a pseudo tag during ExecutorStart 
reappears in later executions with generic plans ...

Is this QueryDesc reusable by a custom plan ? If not maybe a solution
could be to add a flag in queryDesc->plannedstmt ?

(sorry, I haven't understood yet how and when this generic plan is 
managed during planning)

Regards
PAscal



--
Sent from: https://www.postgresql-archive.org/PostgreSQL-hackers-f1928748.html




Re: Is it useful to record whether plans are generic or custom?

2020-05-15 Thread Atsushi Torikoshi
On Thu, May 14, 2020 at 2:28 AM legrand legrand 
wrote:

> Hello,
>
> yes this can be usefull, under the condition of differentiating all the
> counters
> for a queryid using a generic plan and the one using a custom one.
>
> For me one way to do that is adding a generic_plan column to
> pg_stat_statements key, someting like:
> - userid,
> - dbid,
> - queryid,
> - generic_plan
>

Thanks for your kind advice!


> I don't know if generic/custom plan types are available during planning
> and/or
> execution hooks ...


Yeah, that's what I'm concerned about.

As far as I can see, there are no variables tracking executed
plan types so we may need to add variables in
CachedPlanSource or somewhere.

CachedPlanSource.num_custom_plans looked like what is needed,
but it is the number of PLANNING so it also increments when
the planner calculates both plans and decides to take generic
plan.


To track executed plan types, I think execution layer hooks
are appropriate.
These hooks, however, take QueryDesc as a param and it does
not include cached plan information.
Portal includes CachedPlanSource but there seem no hooks to
take Portal.

So I'm wondering it's necessary to add a hook to get Portal
or CachedPlanSource.
Are these too much change for getting plan types?


Regards,

--
Atsushi Torikoshi


Re: Is it useful to record whether plans are generic or custom?

2020-05-13 Thread legrand legrand
Hello,

yes this can be usefull, under the condition of differentiating all the
counters
for a queryid using a generic plan and the one using a custom one.

For me one way to do that is adding a generic_plan column to 
pg_stat_statements key, someting like:
- userid,
- dbid,
- queryid,
- generic_plan

I don't know if generic/custom plan types are available during planning
and/or 
execution hooks ...

Regards
PAscal




--
Sent from: https://www.postgresql-archive.org/PostgreSQL-hackers-f1928748.html