Store ShardInterval instead of shardId in RangeTableFragments.

For CITUS_RTE_RELATION type fragments, reloading shardIntervals from the
database is rather expensive. So store a pointer to the full shard
interval, instead of just the shard id.  There's no new memory lifetime
hazards here, because we already passed a pointer to the shardInterval's
->shardId field around.

The plan time for the query in issue #607 goes from 2889 ms to 106 ms.
with this change.
pull/608/head
Andres Freund 2016-06-16 15:10:25 -07:00
parent 211a9721a9
commit 2e8e8d377e
1 changed files with 28 additions and 20 deletions

View File

@ -2008,7 +2008,7 @@ SubquerySqlTaskList(Job *job)
ShardInterval *shardInterval = (ShardInterval *) lfirst(shardIntervalCell); ShardInterval *shardInterval = (ShardInterval *) lfirst(shardIntervalCell);
RangeTableFragment *shardFragment = palloc0(fragmentSize); RangeTableFragment *shardFragment = palloc0(fragmentSize);
shardFragment->fragmentReference = &(shardInterval->shardId); shardFragment->fragmentReference = shardInterval;
shardFragment->fragmentType = CITUS_RTE_RELATION; shardFragment->fragmentType = CITUS_RTE_RELATION;
shardFragment->rangeTableId = tableId; shardFragment->rangeTableId = tableId;
@ -2449,7 +2449,7 @@ RangeTableFragmentsList(List *rangeTableList, List *whereClauseList,
(ShardInterval *) lfirst(shardIntervalCell); (ShardInterval *) lfirst(shardIntervalCell);
RangeTableFragment *shardFragment = palloc0(fragmentSize); RangeTableFragment *shardFragment = palloc0(fragmentSize);
shardFragment->fragmentReference = &shardInterval->shardId; shardFragment->fragmentReference = shardInterval;
shardFragment->fragmentType = CITUS_RTE_RELATION; shardFragment->fragmentType = CITUS_RTE_RELATION;
shardFragment->rangeTableId = tableId; shardFragment->rangeTableId = tableId;
@ -3582,14 +3582,16 @@ FragmentInterval(RangeTableFragment *fragment)
ShardInterval *fragmentInterval = NULL; ShardInterval *fragmentInterval = NULL;
if (fragment->fragmentType == CITUS_RTE_RELATION) if (fragment->fragmentType == CITUS_RTE_RELATION)
{ {
uint64 *shardId = (uint64 *) fragment->fragmentReference; Assert(CitusIsA(fragment->fragmentReference, ShardInterval));
fragmentInterval = (ShardInterval *) fragment->fragmentReference;
fragmentInterval = LoadShardInterval(*shardId);
} }
else if (fragment->fragmentType == CITUS_RTE_REMOTE_QUERY) else if (fragment->fragmentType == CITUS_RTE_REMOTE_QUERY)
{ {
Task *mergeTask = (Task *) fragment->fragmentReference; Task *mergeTask = NULL;
Assert(CitusIsA(fragment->fragmentReference, Task));
mergeTask = (Task *) fragment->fragmentReference;
fragmentInterval = mergeTask->shardInterval; fragmentInterval = mergeTask->shardInterval;
} }
@ -3687,22 +3689,24 @@ UniqueFragmentList(List *fragmentList)
foreach(fragmentCell, fragmentList) foreach(fragmentCell, fragmentList)
{ {
uint64 *shardId = NULL; ShardInterval *shardInterval = NULL;
bool shardIdAlreadyAdded = false; bool shardIdAlreadyAdded = false;
ListCell *uniqueFragmentCell = NULL; ListCell *uniqueFragmentCell = NULL;
RangeTableFragment *fragment = (RangeTableFragment *) lfirst(fragmentCell); RangeTableFragment *fragment = (RangeTableFragment *) lfirst(fragmentCell);
Assert(fragment->fragmentType == CITUS_RTE_RELATION); Assert(fragment->fragmentType == CITUS_RTE_RELATION);
shardId = fragment->fragmentReference; Assert(CitusIsA(fragment->fragmentReference, ShardInterval));
shardInterval = (ShardInterval *) fragment->fragmentReference;
foreach(uniqueFragmentCell, uniqueFragmentList) foreach(uniqueFragmentCell, uniqueFragmentList)
{ {
RangeTableFragment *uniqueFragment = RangeTableFragment *uniqueFragment =
(RangeTableFragment *) lfirst(uniqueFragmentCell); (RangeTableFragment *) lfirst(uniqueFragmentCell);
uint64 *uniqueShardId = uniqueFragment->fragmentReference; ShardInterval *uniqueShardInterval =
(ShardInterval *) uniqueFragment->fragmentReference;
if (*shardId == *uniqueShardId) if (shardInterval->shardId == uniqueShardInterval->shardId)
{ {
shardIdAlreadyAdded = true; shardIdAlreadyAdded = true;
break; break;
@ -3734,12 +3738,13 @@ DataFetchTaskList(uint64 jobId, uint32 taskIdIndex, List *fragmentList)
RangeTableFragment *fragment = (RangeTableFragment *) lfirst(fragmentCell); RangeTableFragment *fragment = (RangeTableFragment *) lfirst(fragmentCell);
if (fragment->fragmentType == CITUS_RTE_RELATION) if (fragment->fragmentType == CITUS_RTE_RELATION)
{ {
uint64 *shardId = fragment->fragmentReference; ShardInterval *shardInterval = fragment->fragmentReference;
StringInfo shardFetchQueryString = ShardFetchQueryString(*shardId); uint64 shardId = shardInterval->shardId;
StringInfo shardFetchQueryString = ShardFetchQueryString(shardId);
Task *shardFetchTask = CreateBasicTask(jobId, taskIdIndex, SHARD_FETCH_TASK, Task *shardFetchTask = CreateBasicTask(jobId, taskIdIndex, SHARD_FETCH_TASK,
shardFetchQueryString->data); shardFetchQueryString->data);
shardFetchTask->shardId = (*shardId); shardFetchTask->shardId = shardId;
dataFetchTaskList = lappend(dataFetchTaskList, shardFetchTask); dataFetchTaskList = lappend(dataFetchTaskList, shardFetchTask);
taskIdIndex++; taskIdIndex++;
@ -3969,7 +3974,8 @@ FragmentAlias(RangeTblEntry *rangeTableEntry, RangeTableFragment *fragment)
if (fragmentType == CITUS_RTE_RELATION) if (fragmentType == CITUS_RTE_RELATION)
{ {
char *shardAliasName = NULL; char *shardAliasName = NULL;
uint64 *shardId = fragment->fragmentReference; ShardInterval *shardInterval = (ShardInterval *) fragment->fragmentReference;
uint64 shardId = shardInterval->shardId;
Oid relationId = rangeTableEntry->relid; Oid relationId = rangeTableEntry->relid;
char *relationName = get_rel_name(relationId); char *relationName = get_rel_name(relationId);
@ -3991,7 +3997,7 @@ FragmentAlias(RangeTblEntry *rangeTableEntry, RangeTableFragment *fragment)
* If user specified a shard name in pg_dist_shard, use that name in alias. * If user specified a shard name in pg_dist_shard, use that name in alias.
* Otherwise, set shard name in alias to <relation_name>_<shard_id>. * Otherwise, set shard name in alias to <relation_name>_<shard_id>.
*/ */
shardAliasName = LoadShardAlias(relationId, *shardId); shardAliasName = LoadShardAlias(relationId, shardId);
if (shardAliasName != NULL) if (shardAliasName != NULL)
{ {
fragmentName = shardAliasName; fragmentName = shardAliasName;
@ -3999,7 +4005,7 @@ FragmentAlias(RangeTblEntry *rangeTableEntry, RangeTableFragment *fragment)
else else
{ {
char *shardName = pstrdup(relationName); char *shardName = pstrdup(relationName);
AppendShardIdToName(&shardName, *shardId); AppendShardIdToName(&shardName, shardId);
fragmentName = shardName; fragmentName = shardName;
} }
@ -4057,11 +4063,13 @@ AnchorShardId(List *fragmentList, uint32 anchorRangeTableId)
RangeTableFragment *fragment = (RangeTableFragment *) lfirst(fragmentCell); RangeTableFragment *fragment = (RangeTableFragment *) lfirst(fragmentCell);
if (fragment->rangeTableId == anchorRangeTableId) if (fragment->rangeTableId == anchorRangeTableId)
{ {
uint64 *shardIdPointer = NULL; ShardInterval *shardInterval = NULL;
Assert(fragment->fragmentType == CITUS_RTE_RELATION);
shardIdPointer = (uint64 *) fragment->fragmentReference; Assert(fragment->fragmentType == CITUS_RTE_RELATION);
anchorShardId = (*shardIdPointer); Assert(CitusIsA(fragment->fragmentReference, ShardInterval));
shardInterval = (ShardInterval *) fragment->fragmentReference;
anchorShardId = shardInterval->shardId;
break; break;
} }
} }