From a98871b7ac601b4ebe6ba050b1f9cbfdd5d71ded Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 3 Dec 2005 05:51:03 +0000 Subject: Tweak indexscan machinery to avoid taking an AccessShareLock on an index if we already have a stronger lock due to the index's table being the update target table of the query. Same optimization I applied earlier at the table level. There doesn't seem to be much interest in the more radical idea of not locking indexes at all, so do what we can ... --- src/backend/executor/execUtils.c | 24 +++++++++++++++++++++++- src/backend/executor/nodeBitmapIndexscan.c | 13 ++++++++++--- src/backend/executor/nodeIndexscan.c | 12 +++++++++--- 3 files changed, 42 insertions(+), 7 deletions(-) (limited to 'src/backend/executor') diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c index c814b97147..500ff0f4f2 100644 --- a/src/backend/executor/execUtils.c +++ b/src/backend/executor/execUtils.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.130 2005/12/02 20:03:40 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.131 2005/12/03 05:51:01 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -693,6 +693,28 @@ ExecAssignScanTypeFromOuterPlan(ScanState *scanstate) * ---------------------------------------------------------------- */ +/* ---------------------------------------------------------------- + * ExecRelationIsTargetRelation + * + * Detect whether a relation (identified by rangetable index) + * is one of the target relations of the query. + * ---------------------------------------------------------------- + */ +bool +ExecRelationIsTargetRelation(EState *estate, Index scanrelid) +{ + ResultRelInfo *resultRelInfos; + int i; + + resultRelInfos = estate->es_result_relations; + for (i = 0; i < estate->es_num_result_relations; i++) + { + if (resultRelInfos[i].ri_RangeTableIndex == scanrelid) + return true; + } + return false; +} + /* ---------------------------------------------------------------- * ExecOpenScanRelation * diff --git a/src/backend/executor/nodeBitmapIndexscan.c b/src/backend/executor/nodeBitmapIndexscan.c index 4217de3952..114de29ba8 100644 --- a/src/backend/executor/nodeBitmapIndexscan.c +++ b/src/backend/executor/nodeBitmapIndexscan.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/nodeBitmapIndexscan.c,v 1.13 2005/12/02 20:03:40 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/nodeBitmapIndexscan.c,v 1.14 2005/12/03 05:51:01 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -214,6 +214,7 @@ BitmapIndexScanState * ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate) { BitmapIndexScanState *indexstate; + bool relistarget; /* * create state structure @@ -294,13 +295,19 @@ ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate) indexstate->ss.ss_currentScanDesc = NULL; /* - * open the index relation and initialize relation and scan descriptors. + * Open the index relation and initialize relation and scan descriptors. * Note we acquire no locks here; the index machinery does its own locks - * and unlocks. + * and unlocks. (We rely on having a lock on the parent table to + * ensure the index won't go away!) Furthermore, if the parent table + * is one of the target relations of the query, then InitPlan already + * opened and write-locked the index, so we can tell the index machinery + * not to bother getting an extra lock. */ indexstate->biss_RelationDesc = index_open(node->indexid); + relistarget = ExecRelationIsTargetRelation(estate, node->scan.scanrelid); indexstate->biss_ScanDesc = index_beginscan_multi(indexstate->biss_RelationDesc, + !relistarget, estate->es_snapshot, indexstate->biss_NumScanKeys, indexstate->biss_ScanKeys); diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c index 4beecfbd57..94495b4bc7 100644 --- a/src/backend/executor/nodeIndexscan.c +++ b/src/backend/executor/nodeIndexscan.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/nodeIndexscan.c,v 1.108 2005/12/02 20:03:40 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/nodeIndexscan.c,v 1.109 2005/12/03 05:51:02 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -461,6 +461,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate) { IndexScanState *indexstate; Relation currentRelation; + bool relistarget; /* * create state structure @@ -557,14 +558,19 @@ ExecInitIndexScan(IndexScan *node, EState *estate) ExecAssignScanType(&indexstate->ss, RelationGetDescr(currentRelation), false); /* - * open the index relation and initialize relation and scan descriptors. + * Open the index relation and initialize relation and scan descriptors. * Note we acquire no locks here; the index machinery does its own locks * and unlocks. (We rely on having a lock on the parent table to - * ensure the index won't go away!) + * ensure the index won't go away!) Furthermore, if the parent table + * is one of the target relations of the query, then InitPlan already + * opened and write-locked the index, so we can tell the index machinery + * not to bother getting an extra lock. */ indexstate->iss_RelationDesc = index_open(node->indexid); + relistarget = ExecRelationIsTargetRelation(estate, node->scan.scanrelid); indexstate->iss_ScanDesc = index_beginscan(currentRelation, indexstate->iss_RelationDesc, + !relistarget, estate->es_snapshot, indexstate->iss_NumScanKeys, indexstate->iss_ScanKeys); -- cgit v1.2.1