Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit08ae5ed

Browse files
committed
Optimize the case where a btree indexscan has current and mark positions
on the same index page; we can avoid data copying as well as buffer refcountmanipulations in this common case. Makes for a small but noticeableimprovement in mergejoin speed.Heikki Linnakangas
1 parent7ad642d commit08ae5ed

File tree

3 files changed

+67
-26
lines changed

3 files changed

+67
-26
lines changed

‎src/backend/access/nbtree/nbtree.c

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* Portions Copyright (c) 1994, Regents of the University of California
1313
*
1414
* IDENTIFICATION
15-
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.149 2006/05/10 23:18:39 tgl Exp $
15+
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.150 2006/08/24 01:18:34 tgl Exp $
1616
*
1717
*-------------------------------------------------------------------------
1818
*/
@@ -392,6 +392,7 @@ btrescan(PG_FUNCTION_ARGS)
392392
ReleaseBuffer(so->markPos.buf);
393393
so->markPos.buf=InvalidBuffer;
394394
}
395+
so->markItemIndex=-1;
395396

396397
/*
397398
* Reset the scan keys. Note that keys ordering stuff moved to _bt_first.
@@ -430,6 +431,7 @@ btendscan(PG_FUNCTION_ARGS)
430431
ReleaseBuffer(so->markPos.buf);
431432
so->markPos.buf=InvalidBuffer;
432433
}
434+
so->markItemIndex=-1;
433435

434436
if (so->killedItems!=NULL)
435437
pfree(so->killedItems);
@@ -456,14 +458,16 @@ btmarkpos(PG_FUNCTION_ARGS)
456458
so->markPos.buf=InvalidBuffer;
457459
}
458460

459-
/* bump pin on current buffer for assignment to mark buffer */
461+
/*
462+
* Just record the current itemIndex. If we later step to next page
463+
* before releasing the marked position, _bt_steppage makes a full copy
464+
* of the currPos struct in markPos. If (as often happens) the mark is
465+
* moved before we leave the page, we don't have to do that work.
466+
*/
460467
if (BTScanPosIsValid(so->currPos))
461-
{
462-
IncrBufferRefCount(so->currPos.buf);
463-
memcpy(&so->markPos,&so->currPos,
464-
offsetof(BTScanPosData,items[1])+
465-
so->currPos.lastItem*sizeof(BTScanPosItem));
466-
}
468+
so->markItemIndex=so->currPos.itemIndex;
469+
else
470+
so->markItemIndex=-1;
467471

468472
PG_RETURN_VOID();
469473
}
@@ -477,24 +481,35 @@ btrestrpos(PG_FUNCTION_ARGS)
477481
IndexScanDescscan= (IndexScanDesc)PG_GETARG_POINTER(0);
478482
BTScanOpaqueso= (BTScanOpaque)scan->opaque;
479483

480-
/* we aren't holding any read locks, but gotta drop the pin */
481-
if (BTScanPosIsValid(so->currPos))
484+
if (so->markItemIndex >=0)
482485
{
483-
/* Before leaving current page, deal with any killed items */
484-
if (so->numKilled>0&&
485-
so->currPos.buf!=so->markPos.buf)
486-
_bt_killitems(scan, false);
487-
ReleaseBuffer(so->currPos.buf);
488-
so->currPos.buf=InvalidBuffer;
489-
}
490-
491-
/* bump pin on marked buffer */
492-
if (BTScanPosIsValid(so->markPos))
486+
/*
487+
* The mark position is on the same page we are currently on.
488+
* Just restore the itemIndex.
489+
*/
490+
so->currPos.itemIndex=so->markItemIndex;
491+
}
492+
else
493493
{
494-
IncrBufferRefCount(so->markPos.buf);
495-
memcpy(&so->currPos,&so->markPos,
496-
offsetof(BTScanPosData,items[1])+
497-
so->markPos.lastItem*sizeof(BTScanPosItem));
494+
/* we aren't holding any read locks, but gotta drop the pin */
495+
if (BTScanPosIsValid(so->currPos))
496+
{
497+
/* Before leaving current page, deal with any killed items */
498+
if (so->numKilled>0&&
499+
so->currPos.buf!=so->markPos.buf)
500+
_bt_killitems(scan, false);
501+
ReleaseBuffer(so->currPos.buf);
502+
so->currPos.buf=InvalidBuffer;
503+
}
504+
505+
if (BTScanPosIsValid(so->markPos))
506+
{
507+
/* bump pin on mark buffer for assignment to current buffer */
508+
IncrBufferRefCount(so->markPos.buf);
509+
memcpy(&so->currPos,&so->markPos,
510+
offsetof(BTScanPosData,items[1])+
511+
so->markPos.lastItem*sizeof(BTScanPosItem));
512+
}
498513
}
499514

500515
PG_RETURN_VOID();

‎src/backend/access/nbtree/nbtsearch.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.105 2006/05/07 01:21:30 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.106 2006/08/24 01:18:34 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -815,6 +815,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
815815
so->currPos.moreRight= false;
816816
}
817817
so->numKilled=0;/* just paranoia */
818+
so->markItemIndex=-1;/* ditto */
818819

819820
/* position to the precise item on the page */
820821
offnum=_bt_binsrch(rel,buf,keysCount,scankeys,nextkey);
@@ -1053,6 +1054,21 @@ _bt_steppage(IndexScanDesc scan, ScanDirection dir)
10531054
if (so->numKilled>0)
10541055
_bt_killitems(scan, true);
10551056

1057+
/*
1058+
* Before we modify currPos, make a copy of the page data if there
1059+
* was a mark position that needs it.
1060+
*/
1061+
if (so->markItemIndex >=0)
1062+
{
1063+
/* bump pin on current buffer for assignment to mark buffer */
1064+
IncrBufferRefCount(so->currPos.buf);
1065+
memcpy(&so->markPos,&so->currPos,
1066+
offsetof(BTScanPosData,items[1])+
1067+
so->currPos.lastItem*sizeof(BTScanPosItem));
1068+
so->markPos.itemIndex=so->markItemIndex;
1069+
so->markItemIndex=-1;
1070+
}
1071+
10561072
rel=scan->indexRelation;
10571073

10581074
if (ScanDirectionIsForward(dir))
@@ -1408,6 +1424,7 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
14081424
so->currPos.moreRight= false;
14091425
}
14101426
so->numKilled=0;/* just paranoia */
1427+
so->markItemIndex=-1;/* ditto */
14111428

14121429
/*
14131430
* Now load data from the first page of the scan.

‎src/include/access/nbtree.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/access/nbtree.h,v 1.103 2006/08/07 16:57:57 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/access/nbtree.h,v 1.104 2006/08/24 01:18:34 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -438,6 +438,15 @@ typedef struct BTScanOpaqueData
438438
int*killedItems;/* currPos.items indexes of killed items */
439439
intnumKilled;/* number of currently stored items */
440440

441+
/*
442+
* If the marked position is on the same page as current position,
443+
* we don't use markPos, but just keep the marked itemIndex in
444+
* markItemIndex (all the rest of currPos is valid for the mark position).
445+
* Hence, to determine if there is a mark, first look at markItemIndex,
446+
* then at markPos.
447+
*/
448+
intmarkItemIndex;/* itemIndex, or -1 if not valid */
449+
441450
/* keep these last in struct for efficiency */
442451
BTScanPosDatacurrPos;/* current position data */
443452
BTScanPosDatamarkPos;/* marked position, if any */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp