1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-02 09:02:37 +03:00

Tweak indexscan and seqscan code to arrange that steps from one page to

the next are handled by ReleaseAndReadBuffer rather than separate
ReleaseBuffer and ReadBuffer calls.  This cuts the number of acquisitions
of the BufMgrLock by a factor of 2 (possibly more, if an indexscan happens
to pull successive rows from the same heap page).  Unfortunately this
doesn't seem enough to get us out of the recently discussed context-switch
storm problem, but it's surely worth doing anyway.
This commit is contained in:
Tom Lane
2004-04-21 18:24:26 +00:00
parent 95a03e9cdf
commit 37fa3b6c89
11 changed files with 132 additions and 65 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/nodeIndexscan.c,v 1.92 2004/02/28 19:46:05 tgl Exp $
* $PostgreSQL: pgsql/src/backend/executor/nodeIndexscan.c,v 1.93 2004/04/21 18:24:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -128,6 +128,15 @@ IndexNext(IndexScanState *node)
slot = node->ss.ss_ScanTupleSlot;
scanrelid = ((IndexScan *) node->ss.ps.plan)->scan.scanrelid;
/*
* Clear any reference to the previously returned tuple. The idea here
* is to not have the tuple slot be the last holder of a pin on that
* tuple's buffer; if it is, we'll need a separate visit to the bufmgr
* to release the buffer. By clearing here, we get to have the release
* done by ReleaseAndReadBuffer inside index_getnext.
*/
ExecClearTuple(slot);
/*
* Check if we are evaluating PlanQual for tuple of this relation.
* Additional checking is not good, but no other way for now. We could
@ -139,7 +148,6 @@ IndexNext(IndexScanState *node)
{
List *qual;
ExecClearTuple(slot);
if (estate->es_evTupleNull[scanrelid - 1])
return slot; /* return empty slot */

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/nodeSeqscan.c,v 1.47 2003/11/29 19:51:48 pgsql Exp $
* $PostgreSQL: pgsql/src/backend/executor/nodeSeqscan.c,v 1.48 2004/04/21 18:24:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -61,6 +61,15 @@ SeqNext(SeqScanState *node)
direction = estate->es_direction;
slot = node->ss_ScanTupleSlot;
/*
* Clear any reference to the previously returned tuple. The idea here
* is to not have the tuple slot be the last holder of a pin on that
* tuple's buffer; if it is, we'll need a separate visit to the bufmgr
* to release the buffer. By clearing here, we get to have the release
* done by ReleaseAndReadBuffer inside heap_getnext.
*/
ExecClearTuple(slot);
/*
* Check if we are evaluating PlanQual for tuple of this relation.
* Additional checking is not good, but no other way for now. We could
@ -70,7 +79,6 @@ SeqNext(SeqScanState *node)
if (estate->es_evTuple != NULL &&
estate->es_evTuple[scanrelid - 1] != NULL)
{
ExecClearTuple(slot);
if (estate->es_evTupleNull[scanrelid - 1])
return slot; /* return empty slot */

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/nodeTidscan.c,v 1.36 2003/11/29 19:51:48 pgsql Exp $
* $PostgreSQL: pgsql/src/backend/executor/nodeTidscan.c,v 1.37 2004/04/21 18:24:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -106,6 +106,13 @@ TidNext(TidScanState *node)
slot = node->ss.ss_ScanTupleSlot;
scanrelid = ((TidScan *) node->ss.ps.plan)->scan.scanrelid;
/*
* Clear any reference to the previously returned tuple. This doesn't
* offer any great performance benefit, but it keeps this code in sync
* with SeqNext and IndexNext.
*/
ExecClearTuple(slot);
/*
* Check if we are evaluating PlanQual for tuple of this relation.
* Additional checking is not good, but no other way for now. We could
@ -115,7 +122,6 @@ TidNext(TidScanState *node)
if (estate->es_evTuple != NULL &&
estate->es_evTuple[scanrelid - 1] != NULL)
{
ExecClearTuple(slot);
if (estate->es_evTupleNull[scanrelid - 1])
return slot; /* return empty slot */