Query Planning Performance Improvments (#474)

- Only look at pruned shards when determining AnchorTable
- Use cached shardIntervalCompareFunction during copartition check
pull/478/head
Brian Cloutier 2016-05-03 10:48:46 +03:00
parent becac83ac9
commit 58535eb337
2 changed files with 24 additions and 9 deletions

View File

@ -139,7 +139,8 @@ static bool JoinOnPartitionColumn(Query *query);
static void ErrorIfUnsupportedShardDistribution(Query *query); static void ErrorIfUnsupportedShardDistribution(Query *query);
static List * RelationIdList(Query *query); static List * RelationIdList(Query *query);
static bool CoPartitionedTables(Oid firstRelationId, Oid secondRelationId); static bool CoPartitionedTables(Oid firstRelationId, Oid secondRelationId);
static bool ShardIntervalsEqual(ShardInterval *firstInterval, static bool ShardIntervalsEqual(FmgrInfo *comparisonFunction,
ShardInterval *firstInterval,
ShardInterval *secondInterval); ShardInterval *secondInterval);
static void ErrorIfUnsupportedFilters(Query *subquery); static void ErrorIfUnsupportedFilters(Query *subquery);
static bool EqualOpExpressionLists(List *firstOpExpressionList, static bool EqualOpExpressionLists(List *firstOpExpressionList,
@ -3496,6 +3497,7 @@ CoPartitionedTables(Oid firstRelationId, Oid secondRelationId)
secondTableCache->sortedShardIntervalArray; secondTableCache->sortedShardIntervalArray;
uint32 firstListShardCount = firstTableCache->shardIntervalArrayLength; uint32 firstListShardCount = firstTableCache->shardIntervalArrayLength;
uint32 secondListShardCount = secondTableCache->shardIntervalArrayLength; uint32 secondListShardCount = secondTableCache->shardIntervalArrayLength;
FmgrInfo *comparisonFunction = firstTableCache->shardIntervalCompareFunction;
if (firstListShardCount != secondListShardCount) if (firstListShardCount != secondListShardCount)
{ {
@ -3508,12 +3510,16 @@ CoPartitionedTables(Oid firstRelationId, Oid secondRelationId)
return true; return true;
} }
Assert(comparisonFunction != NULL);
for (intervalIndex = 0; intervalIndex < firstListShardCount; intervalIndex++) for (intervalIndex = 0; intervalIndex < firstListShardCount; intervalIndex++)
{ {
ShardInterval *firstInterval = sortedFirstIntervalArray[intervalIndex]; ShardInterval *firstInterval = sortedFirstIntervalArray[intervalIndex];
ShardInterval *secondInterval = sortedSecondIntervalArray[intervalIndex]; ShardInterval *secondInterval = sortedSecondIntervalArray[intervalIndex];
bool shardIntervalsEqual = ShardIntervalsEqual(firstInterval, secondInterval); bool shardIntervalsEqual = ShardIntervalsEqual(comparisonFunction,
firstInterval,
secondInterval);
if (!shardIntervalsEqual) if (!shardIntervalsEqual)
{ {
coPartitionedTables = false; coPartitionedTables = false;
@ -3529,19 +3535,15 @@ CoPartitionedTables(Oid firstRelationId, Oid secondRelationId)
* ShardIntervalsEqual checks if given shard intervals have equal min/max values. * ShardIntervalsEqual checks if given shard intervals have equal min/max values.
*/ */
static bool static bool
ShardIntervalsEqual(ShardInterval *firstInterval, ShardInterval *secondInterval) ShardIntervalsEqual(FmgrInfo *comparisonFunction, ShardInterval *firstInterval,
ShardInterval *secondInterval)
{ {
Oid typeId = InvalidOid;
FmgrInfo *comparisonFunction = NULL;
bool shardIntervalsEqual = false; bool shardIntervalsEqual = false;
Datum firstMin = 0; Datum firstMin = 0;
Datum firstMax = 0; Datum firstMax = 0;
Datum secondMin = 0; Datum secondMin = 0;
Datum secondMax = 0; Datum secondMax = 0;
typeId = firstInterval->valueTypeId;
comparisonFunction = GetFunctionInfo(typeId, BTREE_AM_OID, BTORDER_PROC);
firstMin = firstInterval->minValue; firstMin = firstInterval->minValue;
firstMax = firstInterval->maxValue; firstMax = firstInterval->maxValue;
secondMin = secondInterval->minValue; secondMin = secondInterval->minValue;

View File

@ -1938,6 +1938,7 @@ SubquerySqlTaskList(Job *job)
uint32 anchorRangeTableId = 0; uint32 anchorRangeTableId = 0;
uint32 rangeTableIndex = 0; uint32 rangeTableIndex = 0;
const uint32 fragmentSize = sizeof(RangeTableFragment); const uint32 fragmentSize = sizeof(RangeTableFragment);
uint64 largestTableSize = 0;
/* find filters on partition columns */ /* find filters on partition columns */
ExtractQueryWalker((Node *) subquery, &queryList); ExtractQueryWalker((Node *) subquery, &queryList);
@ -1961,7 +1962,6 @@ SubquerySqlTaskList(Job *job)
/* get list of all range tables in subquery tree */ /* get list of all range tables in subquery tree */
ExtractRangeTableRelationWalker((Node *) subquery, &rangeTableList); ExtractRangeTableRelationWalker((Node *) subquery, &rangeTableList);
anchorRangeTableId = AnchorRangeTableId(rangeTableList);
/* /*
* For each range table entry, first we prune shards for the relation * For each range table entry, first we prune shards for the relation
@ -1979,6 +1979,7 @@ SubquerySqlTaskList(Job *job)
ListCell *shardIntervalCell = NULL; ListCell *shardIntervalCell = NULL;
uint32 tableId = rangeTableIndex + 1; /* tableId starts from 1 */ uint32 tableId = rangeTableIndex + 1; /* tableId starts from 1 */
uint32 finalShardCount = 0; uint32 finalShardCount = 0;
uint64 tableSize = 0;
if (opExpressionList != NIL) if (opExpressionList != NIL)
{ {
@ -2006,6 +2007,8 @@ SubquerySqlTaskList(Job *job)
{ {
ShardInterval *shardInterval = (ShardInterval *) lfirst(shardIntervalCell); ShardInterval *shardInterval = (ShardInterval *) lfirst(shardIntervalCell);
tableSize += ShardLength(shardInterval->shardId);
RangeTableFragment *shardFragment = palloc0(fragmentSize); RangeTableFragment *shardFragment = palloc0(fragmentSize);
shardFragment->fragmentReference = &(shardInterval->shardId); shardFragment->fragmentReference = &(shardInterval->shardId);
shardFragment->fragmentType = CITUS_RTE_RELATION; 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++; rangeTableIndex++;
} }