pg.ddx.io  pgsql-hackers@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Tom Lane <tgl@sss.pgh.pa.us>
To: David Rowley <david.rowley@2ndquadrant.com>
Cc: Jesper Pedersen <jesper.pedersen@redhat.com>
Cc: Andres Freund <andres@anarazel.de>
Cc: Robert Haas <robertmhaas@gmail.com>
Cc: PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Subject: Re: POC: converting Lists into arrays
Date: Fri, 09 Aug 2019 17:03:12 -0400
Message-ID: <14960.1565384592@sss.pgh.pa.us> (raw)
In-Reply-To: <CAKJS1f8wOXdiSWKemGSdqAn_oJq1hNdx=nfZzD0E9zeRUe=p3w@mail.gmail.com>
References: <481.1551390571@sss.pgh.pa.us>
	<24783.1551568303@sss.pgh.pa.us>
	<20190303043424.itzy3ge52xrkpmpr@alap3.anarazel.de>
	<437.1551637744@sss.pgh.pa.us>
	<CA+TgmoZM4c=v0ifR++i09JFtNtnqTq_HkFmbFjwWqbUJffOLmA@mail.gmail.com>
	<12684.1551723095@sss.pgh.pa.us>
	<20190304190612.vgqqsowzkrh22623@alap3.anarazel.de>
	<26464.1551734920@sss.pgh.pa.us>
	<20190304221101.hdg4vj5fo4eewh3b@alap3.anarazel.de>
	<CAKJS1f-pNfoUJrmU8vgD1WrKLqs9WxOVLQ0RpSWu9h6W9RnypA@mail.gmail.com>
	<20190304235402.nod3gbotk2qtd4nh@alap3.anarazel.de>
	<CAKJS1f-yS201hAAmnxcLb2aeTYNZ_A9R1JNXF6hTVXjhHYN7rQ@mail.gmail.com>
	<1131.1551746172@sss.pgh.pa.us>
	<14626.1558745627@sss.pgh.pa.us>
	<29297.1558799327@sss.pgh.pa.us>
	<f078ce63-9e04-0f3e-d200-d7ee66279abe@redhat.com>
	<25178.1562006685@sss.pgh.pa.us>
	<25258.1562023641@sss.pgh.pa.us>
	<CAKJS1f9RUaLrujzpqf15gg_7Wo9-ai7b3-MR=bMH7a-pOWdeZA@mail.gmail.com>
	<2305.1562181615@sss.pgh.pa.us>
	<17220.1565301350@sss.pgh.pa.us>
	<CAKJS1f8wOXdiSWKemGSdqAn_oJq1hNdx=nfZzD0E9zeRUe=p3w@! mail.gmail.com>

David Rowley <david.rowley@2ndquadrant.com> writes:
> On Fri, 9 Aug 2019 at 09:55, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>> I still have hopes for getting rid of es_range_table_array though,
>> and will look at that tomorrow or so.

> Yes, please. I've measured that to be quite an overhead with large
> partitioning setups. However, that was with some additional code which
> didn't lock partitions until it was ... well .... too late... as it
> turned out. But it seems pretty good to remove code that could be a
> future bottleneck if we ever manage to do something else with the
> locking of all partitions during UPDATE/DELETE.

I poked at this, and attached is a patch, but again I'm not seeing
that there's any real performance-based argument for it.  So far
as I can tell, if we've got a lot of RTEs in an executable plan,
the bulk of the startup time is going into lock (re) acquisition in
AcquirePlannerLocks, and/or permissions scanning in ExecCheckRTPerms;
both of those have to do work for every RTE including ones that
run-time pruning drops later on.  ExecInitRangeTable just isn't on
the radar.

If we wanted to try to improve things further, it seems like we'd
have to find a way to not lock unreferenced partitions at all,
as you suggest above.  But combining that with run-time pruning seems
like it'd be pretty horrid from a system structural standpoint: if we
acquire locks only during execution, what happens if we find we must
invalidate the query plan?

Anyway, the attached might be worth committing just on cleanliness
grounds, to avoid two-sources-of-truth issues in the executor.
But it seems like there's no additional performance win here
after all ... unless you've got a test case that shows differently?

			regards, tom lane

Attachments:

  [text/x-diff] remove-es_range_table_array-1.patch (4.0K, ../14960.1565384592@sss.pgh.pa.us/2-remove-es_range_table_array-1.patch)
  download | inline diff:
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index dbd7dd9..7f494ab 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -2790,7 +2790,6 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
 	estate->es_snapshot = parentestate->es_snapshot;
 	estate->es_crosscheck_snapshot = parentestate->es_crosscheck_snapshot;
 	estate->es_range_table = parentestate->es_range_table;
-	estate->es_range_table_array = parentestate->es_range_table_array;
 	estate->es_range_table_size = parentestate->es_range_table_size;
 	estate->es_relations = parentestate->es_relations;
 	estate->es_queryEnv = parentestate->es_queryEnv;
diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
index c1fc0d5..afd9beb 100644
--- a/src/backend/executor/execUtils.c
+++ b/src/backend/executor/execUtils.c
@@ -113,7 +113,6 @@ CreateExecutorState(void)
 	estate->es_snapshot = InvalidSnapshot;	/* caller must initialize this */
 	estate->es_crosscheck_snapshot = InvalidSnapshot;	/* no crosscheck */
 	estate->es_range_table = NIL;
-	estate->es_range_table_array = NULL;
 	estate->es_range_table_size = 0;
 	estate->es_relations = NULL;
 	estate->es_rowmarks = NULL;
@@ -720,29 +719,17 @@ ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags)
  * ExecInitRangeTable
  *		Set up executor's range-table-related data
  *
- * We build an array from the range table list to allow faster lookup by RTI.
- * (The es_range_table field is now somewhat redundant, but we keep it to
- * avoid breaking external code unnecessarily.)
- * This is also a convenient place to set up the parallel es_relations array.
+ * In addition to the range table proper, initialize arrays that are
+ * indexed by rangetable index.
  */
 void
 ExecInitRangeTable(EState *estate, List *rangeTable)
 {
-	Index		rti;
-	ListCell   *lc;
-
 	/* Remember the range table List as-is */
 	estate->es_range_table = rangeTable;
 
-	/* Set up the equivalent array representation */
+	/* Set size of associated arrays */
 	estate->es_range_table_size = list_length(rangeTable);
-	estate->es_range_table_array = (RangeTblEntry **)
-		palloc(estate->es_range_table_size * sizeof(RangeTblEntry *));
-	rti = 0;
-	foreach(lc, rangeTable)
-	{
-		estate->es_range_table_array[rti++] = lfirst_node(RangeTblEntry, lc);
-	}
 
 	/*
 	 * Allocate an array to store an open Relation corresponding to each
@@ -753,8 +740,8 @@ ExecInitRangeTable(EState *estate, List *rangeTable)
 		palloc0(estate->es_range_table_size * sizeof(Relation));
 
 	/*
-	 * es_rowmarks is also parallel to the es_range_table_array, but it's
-	 * allocated only if needed.
+	 * es_rowmarks is also parallel to the es_range_table, but it's allocated
+	 * only if needed.
 	 */
 	estate->es_rowmarks = NULL;
 }
diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h
index 1fb28b4..39c8b3b 100644
--- a/src/include/executor/executor.h
+++ b/src/include/executor/executor.h
@@ -535,8 +535,7 @@ extern void ExecInitRangeTable(EState *estate, List *rangeTable);
 static inline RangeTblEntry *
 exec_rt_fetch(Index rti, EState *estate)
 {
-	Assert(rti > 0 && rti <= estate->es_range_table_size);
-	return estate->es_range_table_array[rti - 1];
+	return (RangeTblEntry *) list_nth(estate->es_range_table, rti - 1);
 }
 
 extern Relation ExecGetRangeTableRelation(EState *estate, Index rti);
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 4ec7849..063b490 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -502,7 +502,6 @@ typedef struct EState
 	Snapshot	es_snapshot;	/* time qual to use */
 	Snapshot	es_crosscheck_snapshot; /* crosscheck time qual for RI */
 	List	   *es_range_table; /* List of RangeTblEntry */
-	struct RangeTblEntry **es_range_table_array;	/* equivalent array */
 	Index		es_range_table_size;	/* size of the range table arrays */
 	Relation   *es_relations;	/* Array of per-range-table-entry Relation
 								 * pointers, or NULL if not yet opened */

view thread (130+ messages)  latest in thread

Message-ID: <14960.1565384592@sss.pgh.pa.us>
Permalink:  ../14960.1565384592@sss.pgh.pa.us/
Also on:    postgresql.org/message-id/14960.1565384592@sss.pgh.pa.us

 ·  · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-hackers@postgresql.org
  Cc: tgl@sss.pgh.pa.us, david.rowley@2ndquadrant.com, jesper.pedersen@redhat.com, andres@anarazel.de, robertmhaas@gmail.com, pgsql-hackers@lists.postgresql.org
  Subject: Re: POC: converting Lists into arrays
  In-Reply-To: <14960.1565384592@sss.pgh.pa.us>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox