解决分区数多时优化器阶段判断部分分区usable属性性能问题

This commit is contained in:
wuyuechuan
2023-12-06 14:20:34 +08:00
parent 930c79aeea
commit cdc368587d
7 changed files with 59 additions and 1 deletions

View File

@ -500,6 +500,7 @@ Relation CopyRelationData(Relation newrel, Relation rel, MemoryContext rules_cxt
newrel->sliceMap = CopyRelationSliceMap(rel);
newrel->entry = NULL;
newrel->rd_ind_partition_all_usable = rel->rd_ind_partition_all_usable;
return newrel;
}

View File

@ -2418,3 +2418,29 @@ bool PartitionMetadataDisabledClean(Relation pgPartition)
}
return result;
}
bool PartCheckPartitionedIndexAllUsable(Relation index_relation)
{
Assert(index_relation->rd_index != NULL);
Oid indrelid = index_relation->rd_index->indrelid;
Relation relation = relation_open(indrelid, NoLock);
if (relation->storage_type == SEGMENT_PAGE) {
relation_close(relation, NoLock);
return false;
}
relation_close(relation, NoLock);
Assert(RelationIsPartitioned(index_relation) && RelationIsIndex(index_relation));
bool result = true;
List* partitions = indexGetPartitionList(index_relation, AccessShareLock);
ListCell* lc = NULL;
foreach(lc, partitions) {
Partition index_partition = (Partition)lfirst(lc);
if (!index_partition->pd_part->indisusable) {
result = false;
break;
}
}
releasePartitionList(index_relation, &partitions, AccessShareLock);
list_free_ext(partitions);
return result;
}

View File

@ -2823,6 +2823,13 @@ void RelationInitIndexAccessInfo(Relation relation, HeapTuple index_tuple)
relation->rd_exclstrats = NULL;
relation->rd_amcache = NULL;
relation->rd_rootcache = InvalidBuffer;
/* check usability status if partitioned index */
if (RelationIsPartitioned(relation)) {
relation->rd_ind_partition_all_usable = PartCheckPartitionedIndexAllUsable(relation);
} else {
relation->rd_ind_partition_all_usable = true; /* trivial for non-partitioned index */
}
}
/*
@ -3513,6 +3520,13 @@ void RelationReloadIndexInfo(Relation relation)
ReleaseSysCache(tuple);
}
/* check usability status if partitioned index */
if (RelationIsPartitioned(relation)) {
relation->rd_ind_partition_all_usable = PartCheckPartitionedIndexAllUsable(relation);
} else {
relation->rd_ind_partition_all_usable = true; /* trivial for non-partitioned index */
}
/* Okay, now it's valid again */
relation->rd_isvalid = true;
}

View File

@ -24798,6 +24798,8 @@ static void ATExecUnusableIndexPartition(Relation rel, const char* partition_nam
AccessExclusiveLock); // lock on heap partition
// call the internal function
ATExecSetIndexUsableState(PartitionRelationId, indexPartOid, false);
/* Invoke cache invalidation to refresh index relation data */
CacheInvalidateRelcache(rel);
}
static void ATUnusableGlobalIndex(Relation rel)
@ -24910,6 +24912,8 @@ static void ATExecUnusableAllIndexOnPartition(Relation rel, const char* partitio
// close index and it's partition
partitionClose(parentIndex, indexPart, NoLock);
index_close(parentIndex, NoLock);
/* Invoke cache invalidation to refresh index relation data */
CacheInvalidateRelcacheByRelid(parentIndId);
}
freePartList(partIndexlist);

View File

@ -205,9 +205,14 @@ bool checkPartitionIndexUnusable(Oid indexOid, int partItrs, PruningResult* prun
/* cannot lock heap in case deadlock, we need process invalid messages here */
AcceptInvalidationMessages();
indexRel = relation_open(indexOid, NoLock);
if (indexRel->rd_ind_partition_all_usable) {
relation_close(indexRel, NoLock);
return true;
}
heapRelOid = IndexGetRelation(indexOid, false);
heapRel = relation_open(heapRelOid, NoLock);
indexRel = relation_open(indexOid, NoLock);
if (RelationIsGlobalIndex(indexRel)) {
partitionIndexUnusable = indexRel->rd_index->indisusable;
relation_close(heapRel, NoLock);
@ -594,6 +599,12 @@ IndexesUsableType eliminate_partition_index_unusable(Oid indexOid, PruningResult
return ret;
}
if (indexRel->rd_ind_partition_all_usable) {
relation_close(heapRel, NoLock);
relation_close(indexRel, NoLock);
return INDEXES_FULL_USABLE;
}
if (!RelationIsPartitioned(heapRel) || !RelationIsPartitioned(indexRel)) {
ereport(ERROR, (errmodule(MOD_OPT),
errcode(ERRCODE_OPTIMIZER_INCONSISTENT_STATE),

View File

@ -106,5 +106,6 @@ extern void PartitionSetAllEnabledClean(Oid parentOid);
extern void PartitionGetAllInvisibleParts(Oid parentOid, OidRBTree** invisibleParts);
extern bool PartitionMetadataDisabledClean(Relation pgPartition);
extern void UpdateWaitCleanGpiRelOptions(Relation pgPartition, HeapTuple partTuple, bool enable, bool inplace);
extern bool PartCheckPartitionedIndexAllUsable(Relation indexRelation);
#endif /* RELCACHE_H */

View File

@ -232,6 +232,7 @@ typedef struct RelationData {
void* rd_amcache; /* available for use by index AM */
Oid* rd_indcollation; /* OIDs of index collations */
Buffer rd_rootcache; /* for root caching */
bool rd_ind_partition_all_usable;
/*
* foreign-table support