Navigation Menu

Skip to content

Commit

Permalink
[YSQL] #1232: Remove unnecessary YSQL index update preparation
Browse files Browse the repository at this point in the history
Summary:
This revision optimizes YSQL index updates by avoiding unnecessary index update preparation when there is no secondary index.
Specifically it correctly excludes from index updates the primary-key index (in primary-key-organized tables).

Test Plan: Jenkins

Reviewers: mihnea

Reviewed By: mihnea

Subscribers: neha, yql

Differential Revision: https://phabricator.dev.yugabyte.com/D6502
  • Loading branch information
robertpang committed Apr 20, 2019
1 parent ef6150a commit 20d5227
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 23 deletions.
28 changes: 22 additions & 6 deletions src/postgres/src/backend/catalog/indexing.c
Expand Up @@ -107,6 +107,13 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple)
*/
for (i = 0; i < numIndexes; i++)
{
/*
* No need to update YugaByte primary key which is intrinic part of
* the base table.
*/
if (IsYugaByteEnabled() && relationDescs[i]->rd_index->indisprimary)
continue;

IndexInfo *indexInfo;

indexInfo = indexInfoArray[i];
Expand Down Expand Up @@ -190,6 +197,13 @@ CatalogIndexDelete(CatalogIndexState indstate, HeapTuple heapTuple)
*/
for (i = 0; i < numIndexes; i++)
{
/*
* No need to update YugaByte primary key which is intrinic part of
* the base table.
*/
if (IsYugaByteEnabled() && relationDescs[i]->rd_index->indisprimary)
continue;

IndexInfo *indexInfo;

indexInfo = indexInfoArray[i];
Expand Down Expand Up @@ -318,9 +332,10 @@ CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)

if (IsYugaByteEnabled())
{
HeapTuple oldtup = NULL;
HeapTuple oldtup = NULL;
bool has_indices = HasYBSecondaryIndices(heapRel);

if (heapRel->rd_rel->relhasindex)
if (has_indices)
{
if (tup->t_ybctid)
{
Expand All @@ -336,7 +351,7 @@ CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
/* Update the local cache automatically */
YBSetSysCacheTuple(heapRel, tup);

if (heapRel->rd_rel->relhasindex)
if (has_indices)
CatalogIndexInsert(indstate, tup);
}
else
Expand All @@ -363,9 +378,10 @@ CatalogTupleUpdateWithInfo(Relation heapRel, ItemPointer otid, HeapTuple tup,
{
if (IsYugaByteEnabled())
{
HeapTuple oldtup = NULL;
HeapTuple oldtup = NULL;
bool has_indices = HasYBSecondaryIndices(heapRel);

if (heapRel->rd_rel->relhasindex)
if (has_indices)
{
if (tup->t_ybctid)
{
Expand All @@ -381,7 +397,7 @@ CatalogTupleUpdateWithInfo(Relation heapRel, ItemPointer otid, HeapTuple tup,
/* Update the local cache automatically */
YBSetSysCacheTuple(heapRel, tup);

if (heapRel->rd_rel->relhasindex)
if (has_indices)
CatalogIndexInsert(indstate, tup);
}
else
Expand Down
14 changes: 14 additions & 0 deletions src/postgres/src/backend/executor/execIndexing.c
Expand Up @@ -322,6 +322,13 @@ ExecInsertIndexTuples(TupleTableSlot *slot,

indexInfo = indexInfoArray[i];

/*
* No need to update YugaByte primary key which is intrinic part of
* the base table.
*/
if (IsYugaByteEnabled() && indexRelation->rd_index->indisprimary)
continue;

/* If the index is marked as read-only, ignore it */
if (!indexInfo->ii_ReadyForInserts)
continue;
Expand Down Expand Up @@ -515,6 +522,13 @@ ExecDeleteIndexTuples(Datum ybctid, HeapTuple tuple, EState *estate)
if (indexRelation == NULL)
continue;

/*
* No need to update YugaByte primary key which is intrinic part of
* the base table.
*/
if (IsYugaByteEnabled() && indexRelation->rd_index->indisprimary)
continue;

indexInfo = indexInfoArray[i];

/* If the index is marked as read-only, ignore it */
Expand Down
39 changes: 24 additions & 15 deletions src/postgres/src/backend/executor/nodeModifyTable.c
Expand Up @@ -94,6 +94,17 @@ static void ExecSetupChildParentMapForSubplan(ModifyTableState *mtstate);
static TupleConversionMap *tupconv_map_for_subplan(ModifyTableState *node,
int whichplan);

/*
* Returns if a table has secondary indices.
*/
static bool
HasSecondaryIndices(ResultRelInfo *resultRelInfo)
{
return resultRelInfo->ri_NumIndices > 1 ||
(resultRelInfo->ri_NumIndices == 1 &&
!resultRelInfo->ri_IndexRelationDescs[0]->rd_index->indisprimary);
}

/*
* Verify that the tuples to be produced by INSERT or UPDATE match the
* target relation's rowtype
Expand Down Expand Up @@ -430,10 +441,7 @@ ExecInsert(ModifyTableState *mtstate,
bool has_triggers = resultRelInfo->ri_TrigDesc &&
resultRelInfo->ri_TrigDesc->numtriggers > 0;

bool has_indices = resultRelInfo->ri_NumIndices > 1 ||
(resultRelInfo->ri_NumIndices == 1 &&
!resultRelInfo->ri_IndexRelationDescs[0]->rd_index
->indisprimary);
bool has_indices = HasSecondaryIndices(resultRelInfo);

bool is_single_row_txn = estate->es_yb_is_single_row_modify_txn &&
!has_indices &&
Expand All @@ -452,7 +460,7 @@ ExecInsert(ModifyTableState *mtstate,
tuple);
}

if (resultRelInfo->ri_NumIndices > 0)
if (HasSecondaryIndices(resultRelInfo))
{
/* insert index entries for tuple */
recheckIndexes = ExecInsertIndexTuples(slot, tuple,
Expand Down Expand Up @@ -782,7 +790,7 @@ ExecDelete(ModifyTableState *mtstate,
{
YBCExecuteDelete(resultRelationDesc, planSlot);

if (resultRelInfo->ri_NumIndices > 0)
if (HasSecondaryIndices(resultRelInfo))
{
Datum ybctid = YBCGetYBTupleIdFromSlot(planSlot);

Expand Down Expand Up @@ -1117,7 +1125,7 @@ ExecUpdate(ModifyTableState *mtstate,
if (resultRelInfo->ri_projectReturning)
slot = ExecFilterJunk(resultRelInfo->ri_junkFilter, planSlot);

if (resultRelInfo->ri_NumIndices > 0)
if (HasSecondaryIndices(resultRelInfo))
{
Datum ybctid = YBCGetYBTupleIdFromSlot(planSlot);

Expand Down Expand Up @@ -2210,9 +2218,8 @@ ExecModifyTable(PlanState *pstate)
* wholerow junk attribute with the ybctid for removing old
* index entries for UPDATE and DELETE.
*/
if (IsYugaByteEnabled() &&
IsYBRelation(resultRelInfo->ri_RelationDesc) &&
(resultRelInfo->ri_NumIndices > 0))
if (IsYBRelation(resultRelInfo->ri_RelationDesc) &&
HasSecondaryIndices(resultRelInfo))
{
resno = ExecFindJunkAttribute(junkfilter, "wholerow");
datum = ExecGetJunkAttribute(slot, resno, &isNull);
Expand Down Expand Up @@ -2434,12 +2441,14 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
* already, since we share the resultrel state with the original
* query.
*
* For a YugaByte table, we delete the old index entries during DELETE so
* the indexes need to be opened still.
* For a YugaByte table, we need to update the secondary indices for
* all of the INSERT, UPDATE, and DELETE statements.
*/
if (resultRelInfo->ri_RelationDesc->rd_rel->relhasindex &&
(operation != CMD_DELETE || IsYugaByteEnabled()) &&
resultRelInfo->ri_IndexRelationDescs == NULL)
if ((IsYBRelation(resultRelInfo->ri_RelationDesc) ?
HasYBSecondaryIndices(resultRelInfo->ri_RelationDesc) :
(resultRelInfo->ri_RelationDesc->rd_rel->relhasindex &&
operation != CMD_DELETE)) &&
resultRelInfo->ri_IndexRelationDescs == NULL)
ExecOpenIndices(resultRelInfo,
node->onConflictAction != ONCONFLICT_NONE);

Expand Down
4 changes: 2 additions & 2 deletions src/postgres/src/backend/rewrite/rewriteHandler.c
Expand Up @@ -1319,9 +1319,9 @@ rewriteTargetListUD(Query *parsetree, RangeTblEntry *target_rte,
if (IsYBRelation(target_relation))
{
/*
* If there are indexes on the target table, return the whole row also.
* If there are secondary indices on the target table, return the whole row also.
*/
if (target_relation->rd_rel->relhasindex)
if (HasYBSecondaryIndices(target_relation))
{
var = makeWholeRowVar(target_rte,
parsetree->resultRelation,
Expand Down
23 changes: 23 additions & 0 deletions src/postgres/src/backend/utils/misc/pg_yb_utils.c
Expand Up @@ -104,6 +104,29 @@ IsYBRelationById(Oid relid)
return is_supported;
}

bool
HasYBSecondaryIndices(Relation relation)
{
if (!relation->rd_rel->relhasindex)
return false;

bool has_indices = false;
List *indexlist = RelationGetIndexList(relation);
ListCell *lc;

foreach(lc, indexlist)
{
if (lfirst_oid(lc) == relation->rd_pkindex)
continue;
has_indices = true;
break;
}

list_free(indexlist);

return has_indices;
}

bool
YBNeedRetryAfterCacheRefresh(ErrorData *edata)
{
Expand Down
2 changes: 2 additions & 0 deletions src/postgres/src/include/pg_yb_utils.h
Expand Up @@ -83,6 +83,8 @@ extern bool IsYBRelationById(Oid relid);

extern bool IsYBRelation(Relation relation);

extern bool HasYBSecondaryIndices(Relation relation);

extern bool YBNeedRetryAfterCacheRefresh(ErrorData *error);

extern void YBReportFeatureUnsupported(const char *err_msg);
Expand Down

0 comments on commit 20d5227

Please sign in to comment.