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 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;

View File

@ -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++;
}