From fbe0b94cc535bcdc85eabd916f211d44aa411fca Mon Sep 17 00:00:00 2001 From: Brian Cloutier Date: Wed, 27 Apr 2016 05:05:02 -0700 Subject: [PATCH] Query Planning Performance Improvments - Only look at pruned shards when determining AnchorTable - Use cached shardIntervalCompareFunction during copartition check --- .../planner/multi_logical_optimizer.c | 18 ++++++++++-------- .../planner/multi_physical_planner.c | 15 ++++++++++++++- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/backend/distributed/planner/multi_logical_optimizer.c b/src/backend/distributed/planner/multi_logical_optimizer.c index e68804d8c..784982894 100644 --- a/src/backend/distributed/planner/multi_logical_optimizer.c +++ b/src/backend/distributed/planner/multi_logical_optimizer.c @@ -139,7 +139,8 @@ static bool JoinOnPartitionColumn(Query *query); static void ErrorIfUnsupportedShardDistribution(Query *query); static List * RelationIdList(Query *query); static bool CoPartitionedTables(Oid firstRelationId, Oid secondRelationId); -static bool ShardIntervalsEqual(ShardInterval *firstInterval, +static bool ShardIntervalsEqual(FmgrInfo *comparisonFunction, + ShardInterval *firstInterval, ShardInterval *secondInterval); static void ErrorIfUnsupportedFilters(Query *subquery); static bool EqualOpExpressionLists(List *firstOpExpressionList, @@ -3496,6 +3497,7 @@ CoPartitionedTables(Oid firstRelationId, Oid secondRelationId) secondTableCache->sortedShardIntervalArray; uint32 firstListShardCount = firstTableCache->shardIntervalArrayLength; uint32 secondListShardCount = secondTableCache->shardIntervalArrayLength; + FmgrInfo *comparisonFunction = firstTableCache->shardIntervalCompareFunction; if (firstListShardCount != secondListShardCount) { @@ -3508,12 +3510,16 @@ CoPartitionedTables(Oid firstRelationId, Oid secondRelationId) return true; } + Assert(comparisonFunction != NULL); + for (intervalIndex = 0; intervalIndex < firstListShardCount; intervalIndex++) { ShardInterval *firstInterval = sortedFirstIntervalArray[intervalIndex]; ShardInterval *secondInterval = sortedSecondIntervalArray[intervalIndex]; - bool shardIntervalsEqual = ShardIntervalsEqual(firstInterval, secondInterval); + bool shardIntervalsEqual = ShardIntervalsEqual(comparisonFunction, + firstInterval, + secondInterval); if (!shardIntervalsEqual) { coPartitionedTables = false; @@ -3529,19 +3535,15 @@ CoPartitionedTables(Oid firstRelationId, Oid secondRelationId) * ShardIntervalsEqual checks if given shard intervals have equal min/max values. */ static bool -ShardIntervalsEqual(ShardInterval *firstInterval, ShardInterval *secondInterval) +ShardIntervalsEqual(FmgrInfo *comparisonFunction, ShardInterval *firstInterval, + ShardInterval *secondInterval) { - Oid typeId = InvalidOid; - FmgrInfo *comparisonFunction = NULL; bool shardIntervalsEqual = false; Datum firstMin = 0; Datum firstMax = 0; Datum secondMin = 0; Datum secondMax = 0; - typeId = firstInterval->valueTypeId; - comparisonFunction = GetFunctionInfo(typeId, BTREE_AM_OID, BTORDER_PROC); - firstMin = firstInterval->minValue; firstMax = firstInterval->maxValue; secondMin = secondInterval->minValue; diff --git a/src/backend/distributed/planner/multi_physical_planner.c b/src/backend/distributed/planner/multi_physical_planner.c index 45f364c3d..88675c1b6 100644 --- a/src/backend/distributed/planner/multi_physical_planner.c +++ b/src/backend/distributed/planner/multi_physical_planner.c @@ -1938,6 +1938,7 @@ SubquerySqlTaskList(Job *job) uint32 anchorRangeTableId = 0; uint32 rangeTableIndex = 0; const uint32 fragmentSize = sizeof(RangeTableFragment); + uint64 largestTableSize = 0; /* find filters on partition columns */ ExtractQueryWalker((Node *) subquery, &queryList); @@ -1961,7 +1962,6 @@ SubquerySqlTaskList(Job *job) /* get list of all range tables in subquery tree */ ExtractRangeTableRelationWalker((Node *) subquery, &rangeTableList); - anchorRangeTableId = AnchorRangeTableId(rangeTableList); /* * For each range table entry, first we prune shards for the relation @@ -1979,6 +1979,7 @@ SubquerySqlTaskList(Job *job) ListCell *shardIntervalCell = NULL; uint32 tableId = rangeTableIndex + 1; /* tableId starts from 1 */ uint32 finalShardCount = 0; + uint64 tableSize = 0; if (opExpressionList != NIL) { @@ -2006,6 +2007,8 @@ SubquerySqlTaskList(Job *job) { ShardInterval *shardInterval = (ShardInterval *) lfirst(shardIntervalCell); + tableSize += ShardLength(shardInterval->shardId); + RangeTableFragment *shardFragment = palloc0(fragmentSize); shardFragment->fragmentReference = &(shardInterval->shardId); shardFragment->fragmentType = CITUS_RTE_RELATION; @@ -2027,6 +2030,16 @@ SubquerySqlTaskList(Job *job) } } + /* + * Determine anchor table using shards which survive pruning instead of calling + * AnchorRangeTableId + */ + if (anchorRangeTableId == 0 || tableSize > largestTableSize) + { + largestTableSize = tableSize; + anchorRangeTableId = tableId; + } + rangeTableIndex++; }