aboutsummaryrefslogtreecommitdiff
path: root/src/include/executor/execPartition.h
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2018-04-07 17:54:31 -0300
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2018-04-07 17:54:39 -0300
commit499be013de65242235ebdde06adb08db887f0ea5 (patch)
treec1f69b818f917379fb4f72e80535fef899a40b5b /src/include/executor/execPartition.h
parent5c0675215e153ba1297fd494b34af2fdebd645d1 (diff)
downloadpostgresql-499be013de65242235ebdde06adb08db887f0ea5.tar.gz
postgresql-499be013de65242235ebdde06adb08db887f0ea5.zip
Support partition pruning at execution time
Existing partition pruning is only able to work at plan time, for query quals that appear in the parsed query. This is good but limiting, as there can be parameters that appear later that can be usefully used to further prune partitions. This commit adds support for pruning subnodes of Append which cannot possibly contain any matching tuples, during execution, by evaluating Params to determine the minimum set of subnodes that can possibly match. We support more than just simple Params in WHERE clauses. Support additionally includes: 1. Parameterized Nested Loop Joins: The parameter from the outer side of the join can be used to determine the minimum set of inner side partitions to scan. 2. Initplans: Once an initplan has been executed we can then determine which partitions match the value from the initplan. Partition pruning is performed in two ways. When Params external to the plan are found to match the partition key we attempt to prune away unneeded Append subplans during the initialization of the executor. This allows us to bypass the initialization of non-matching subplans meaning they won't appear in the EXPLAIN or EXPLAIN ANALYZE output. For parameters whose value is only known during the actual execution then the pruning of these subplans must wait. Subplans which are eliminated during this stage of pruning are still visible in the EXPLAIN output. In order to determine if pruning has actually taken place, the EXPLAIN ANALYZE must be viewed. If a certain Append subplan was never executed due to the elimination of the partition then the execution timing area will state "(never executed)". Whereas, if, for example in the case of parameterized nested loops, the number of loops stated in the EXPLAIN ANALYZE output for certain subplans may appear lower than others due to the subplan having been scanned fewer times. This is due to the list of matching subnodes having to be evaluated whenever a parameter which was found to match the partition key changes. This commit required some additional infrastructure that permits the building of a data structure which is able to perform the translation of the matching partition IDs, as returned by get_matching_partitions, into the list index of a subpaths list, as exist in node types such as Append, MergeAppend and ModifyTable. This allows us to translate a list of clauses into a Bitmapset of all the subpath indexes which must be included to satisfy the clause list. Author: David Rowley, based on an earlier effort by Beena Emerson Reviewers: Amit Langote, Robert Haas, Amul Sul, Rajkumar Raghuwanshi, Jesper Pedersen Discussion: https://postgr.es/m/CAOG9ApE16ac-_VVZVvv0gePSgkg_BwYEV1NBqZFqDR2bBE0X0A@mail.gmail.com
Diffstat (limited to 'src/include/executor/execPartition.h')
-rw-r--r--src/include/executor/execPartition.h77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/include/executor/execPartition.h b/src/include/executor/execPartition.h
index 63c883093ea..b2daf24c41d 100644
--- a/src/include/executor/execPartition.h
+++ b/src/include/executor/execPartition.h
@@ -17,6 +17,7 @@
#include "nodes/execnodes.h"
#include "nodes/parsenodes.h"
#include "nodes/plannodes.h"
+#include "partitioning/partprune.h"
/*-----------------------
* PartitionDispatch - information about one partitioned table in a partition
@@ -108,6 +109,77 @@ typedef struct PartitionTupleRouting
TupleTableSlot *root_tuple_slot;
} PartitionTupleRouting;
+/*-----------------------
+ * PartitionPruningData - Encapsulates all information required to support
+ * elimination of partitions in node types which support arbitrary Lists of
+ * subplans. Information stored here allows the planner's partition pruning
+ * functions to be called and the return value of partition indexes translated
+ * into the subpath indexes of node types such as Append, thus allowing us to
+ * bypass certain subnodes when we have proofs that indicate that no tuple
+ * matching the 'pruning_steps' will be found within.
+ *
+ * subnode_map An array containing the subnode index which
+ * matches this partition index, or -1 if the
+ * subnode has been pruned already.
+ * subpart_map An array containing the offset into the
+ * 'partprunedata' array in PartitionPruning, or
+ * -1 if there is no such element in that array.
+ * present_parts A Bitmapset of the partition index that we have
+ * subnodes mapped for.
+ * context Contains the context details required to call
+ * the partition pruning code.
+ * pruning_steps Contains a list of PartitionPruneStep used to
+ * perform the actual pruning.
+ * extparams Contains paramids of external params found
+ * matching partition keys in 'pruning_steps'.
+ * allparams As 'extparams' but also including exec params.
+ *-----------------------
+ */
+typedef struct PartitionPruningData
+{
+ int *subnode_map;
+ int *subpart_map;
+ Bitmapset *present_parts;
+ PartitionPruneContext context;
+ List *pruning_steps;
+ Bitmapset *extparams;
+ Bitmapset *allparams;
+} PartitionPruningData;
+
+/*-----------------------
+ * PartitionPruneState - State object required for executor nodes to perform
+ * partition pruning elimination of their subnodes. This encapsulates a
+ * flattened hierarchy of PartitionPruningData structs and also stores all
+ * paramids which were found to match the partition keys of each partition.
+ * This struct can be attached to node types which support arbitrary Lists of
+ * subnodes containing partitions to allow subnodes to be eliminated due to
+ * the clauses being unable to match to any tuple that the subnode could
+ * possibly produce.
+ *
+ * partprunedata Array of PartitionPruningData for the node's target
+ * partitioned relation. First element contains the
+ * details for the target partitioned table.
+ * num_partprunedata Number of items in 'partprunedata' array.
+ * prune_context A memory context which can be used to call the query
+ * planner's partition prune functions.
+ * extparams All PARAM_EXTERN paramids which were found to match a
+ * partition key in each of the contained
+ * PartitionPruningData structs.
+ * execparams As above but for PARAM_EXEC.
+ * allparams Union of 'extparams' and 'execparams', saved to avoid
+ * recalculation.
+ *-----------------------
+ */
+typedef struct PartitionPruneState
+{
+ PartitionPruningData *partprunedata;
+ int num_partprunedata;
+ MemoryContext prune_context;
+ Bitmapset *extparams;
+ Bitmapset *execparams;
+ Bitmapset *allparams;
+} PartitionPruneState;
+
extern PartitionTupleRouting *ExecSetupPartitionTupleRouting(ModifyTableState *mtstate,
Relation rel);
extern int ExecFindPartition(ResultRelInfo *resultRelInfo,
@@ -133,5 +205,10 @@ extern HeapTuple ConvertPartitionTupleSlot(TupleConversionMap *map,
TupleTableSlot **p_my_slot);
extern void ExecCleanupTupleRouting(ModifyTableState *mtstate,
PartitionTupleRouting *proute);
+extern PartitionPruneState *ExecSetupPartitionPruneState(PlanState *planstate,
+ List *partitionpruneinfo);
+extern Bitmapset *ExecFindMatchingSubPlans(PartitionPruneState *prunestate);
+extern Bitmapset *ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate,
+ int nsubnodes);
#endif /* EXECPARTITION_H */