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.cindex 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.cindex 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.hindex 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.hindex 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 */
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