mirror of https://github.com/citusdata/citus.git
Query Planning Performance Improvments (#474)
- Only look at pruned shards when determining AnchorTable - Use cached shardIntervalCompareFunction during copartition checkpull/1938/head
parent
5b5e18b0bd
commit
5962c9b7c8
|
@ -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;
|
||||||
|
|
|
@ -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++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue