postgresql/src/backend
David Rowley 3592e0ff98 Have ExecFindPartition cache the last found partition
Here we add code which detects when ExecFindPartition() continually finds
the same partition and add a caching layer to improve partition lookup
performance for such cases.

Both RANGE and LIST partitioned tables traditionally require a binary
search for the set of Datums that a partition needs to be found for. This
binary search is commonly visible in profiles when bulk loading into a
partitioned table.  Here we aim to reduce the overhead of bulk-loading
into partitioned tables for cases where many consecutive tuples belong to
the same partition and make the performance of this operation closer to
what it is with a traditional non-partitioned table.

When we find the same partition 16 times in a row, the next search will
result in us simply just checking if the current set of values belongs to
the last found partition.  For LIST partitioning we record the index into
the PartitionBoundInfo's datum array.  This allows us to check if the
current Datum is the same as the Datum that was last looked up.  This
means if any given LIST partition supports storing multiple different
Datum values, then the caching only works when we find the same value as
we did the last time.  For RANGE partitioning we simply check if the given
Datums are in the same range as the previously found partition.

We store the details of the cached partition in PartitionDesc (i.e.
relcache) so that the cached values are maintained over multiple
statements.

No caching is done for HASH partitions.  The majority of the cost in HASH
partition lookups are in the hashing function(s), which would also have to
be executed if we were to try to do caching for HASH partitioned tables.
Since most of the cost is already incurred, we just don't bother.  We also
don't do any caching for LIST partitions when we continually find the
values being looked up belong to the DEFAULT partition.  We've no
corresponding index in the PartitionBoundInfo's datum array for this case.
We also don't cache when we find the given values match to a LIST
partitioned table's NULL partition.  This is so cheap that there's no
point in doing any caching for this.  We also don't cache for a RANGE
partitioned table's DEFAULT partition.

There have been a number of different patches submitted to improve
partition lookups. Hou, Zhijie submitted a patch to detect when the value
belonging to the partition key column(s) were constant and added code to
cache the partition in that case.  Amit Langote then implemented an idea
suggested by me to remember the last found partition and start to check if
the current values work for that partition.  The final patch here was
written by me and was done by taking many of the ideas I liked from the
patches in the thread and redesigning other aspects.

Discussion: https://postgr.es/m/OS0PR01MB571649B27E912EA6CC4EEF03942D9%40OS0PR01MB5716.jpnprd01.prod.outlook.com
Author: Amit Langote, Hou Zhijie, David Rowley
Reviewed-by: Amit Langote, Hou Zhijie
2022-08-02 09:55:27 +12:00
..
access Improve speed of hash index build. 2022-07-28 14:34:32 -04:00
bootstrap Process session_preload_libraries within InitPostgres's transaction. 2022-07-25 10:27:43 -04:00
catalog Support pg_read_[binary_]file (filename, missing_ok). 2022-07-29 15:38:49 -04:00
commands Feed ObjectAddress to event triggers for ALTER TABLE ATTACH/DETACH 2022-07-31 13:04:43 +09:00
executor Have ExecFindPartition cache the last found partition 2022-08-02 09:55:27 +12:00
foreign Create routine able to set single-call SRFs for Materialize mode 2022-03-07 10:26:29 +09:00
jit Pre-beta mechanical code beautification. 2022-05-12 15:17:30 -04:00
lib Fix lock assertions in dshash.c. 2022-07-11 16:43:29 +12:00
libpq Log details for client certificate failures 2022-07-15 17:04:48 +02:00
main Remove support for Visual Studio 2013 2022-07-14 11:22:49 +09:00
nodes Dump more fields when dumping planner internal data structures. 2022-07-20 13:54:30 -04:00
optimizer Fix incorrect is-this-the-topmost-join tests in parallel planning. 2022-07-30 13:05:15 -04:00
parser Check maximum number of columns in function RTEs, too. 2022-08-01 12:22:35 -04:00
partitioning Have ExecFindPartition cache the last found partition 2022-08-02 09:55:27 +12:00
po NLS: Put list of available languages into LINGUAS files 2022-07-13 08:19:17 +02:00
port Emulate sigprocmask(), not sigsetmask(), on Windows. 2022-07-16 17:03:38 +12:00
postmaster Reduce overhead of renaming archive status files. 2022-07-26 16:00:18 +09:00
regex Remove redundant null pointer checks before free() 2022-07-03 11:47:15 +02:00
replication Clean up some residual confusion between OIDs and RelFileNumbers. 2022-07-28 10:20:29 -04:00
rewrite Replace many MemSet calls with struct initialization 2022-07-16 08:50:49 +02:00
snowball Move snowball_create.sql creation into perl file 2022-07-18 12:24:27 -07:00
statistics Invent qsort_interruptible(). 2022-07-12 16:30:36 -04:00
storage Use TRUNCATE to preserve relfilenode for pg_largeobject + index. 2022-07-28 16:03:42 -04:00
tcop Force immediate commit after CREATE DATABASE etc in extended protocol. 2022-07-26 13:07:03 -04:00
tsearch Invent qsort_interruptible(). 2022-07-12 16:30:36 -04:00
utils Fix trim_array() for zero-dimensional array argument. 2022-07-31 13:43:17 -04:00
.gitignore Add .gitignore entries for AIX-specific intermediate build artifacts. 2015-07-08 20:44:22 -04:00
common.mk Remove PARTIAL_LINKING build mode. 2018-03-30 17:33:04 -07:00
Makefile Automatically generate node support functions 2022-07-09 08:53:59 +02:00
nls.mk NLS: Put list of available languages into LINGUAS files 2022-07-13 08:19:17 +02:00