Commit 7b2a8e4e authored by Bruce Momjian's avatar Bruce Momjian

Currently,only the first column of multi-column indices

is used to find start scan position of Indexscan-s.

To speed up finding scan start position,I have changed
_bt_first() to use as many keys as possible.

I'll attach the patch here.

Regards.

Hiroshi Inoue
parent 62045e67
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.53 1999/07/17 20:16:43 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.54 1999/09/27 18:20:21 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -727,10 +727,14 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) ...@@ -727,10 +727,14 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
RegProcedure proc; RegProcedure proc;
int result; int result;
BTScanOpaque so; BTScanOpaque so;
ScanKeyData skdata;
Size keysok; Size keysok;
int i;
int nKeyIndex = -1; bool strategyCheck;
ScanKey scankeys = 0;
int keysCount = 0;
int *nKeyIs = 0;
int i, j;
StrategyNumber strat_total;
rel = scan->relation; rel = scan->relation;
so = (BTScanOpaque) scan->opaque; so = (BTScanOpaque) scan->opaque;
...@@ -742,38 +746,57 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) ...@@ -742,38 +746,57 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
so->numberOfFirstKeys = 0; /* may be changed by _bt_orderkeys */ so->numberOfFirstKeys = 0; /* may be changed by _bt_orderkeys */
so->qual_ok = 1; /* may be changed by _bt_orderkeys */ so->qual_ok = 1; /* may be changed by _bt_orderkeys */
scan->scanFromEnd = false; scan->scanFromEnd = false;
strategyCheck = false;
if (so->numberOfKeys > 0) if (so->numberOfKeys > 0)
{ {
_bt_orderkeys(rel, so); _bt_orderkeys(rel, so);
if (ScanDirectionIsBackward(dir)) if (so->qual_ok)
strategyCheck = true;
}
strat_total = BTEqualStrategyNumber;
if (strategyCheck)
{ {
for (i = 0; i < so->numberOfKeys; i++) AttrNumber attno;
nKeyIs = (int *)palloc(so->numberOfKeys*sizeof(int));
for (i=0; i < so->numberOfKeys; i++)
{ {
if (so->keyData[i].sk_attno != 1) attno = so->keyData[i].sk_attno;
if (attno == keysCount)
continue;
if (attno > keysCount + 1)
break; break;
strat = _bt_getstrat(rel, so->keyData[i].sk_attno, strat = _bt_getstrat(rel, attno,
so->keyData[i].sk_procedure); so->keyData[i].sk_procedure);
if (strat == BTLessStrategyNumber || if (strat == strat_total ||
strat == BTLessEqualStrategyNumber ||
strat == BTEqualStrategyNumber) strat == BTEqualStrategyNumber)
{ {
nKeyIndex = i; nKeyIs[keysCount++] = i;
break; continue;
}
} }
if (ScanDirectionIsBackward(dir) &&
(strat == BTLessStrategyNumber ||
strat == BTLessEqualStrategyNumber) )
{
nKeyIs[keysCount++] = i;
strat_total = strat;
if (strat == BTLessStrategyNumber)
break;
continue;
} }
else if (ScanDirectionIsForward(dir) &&
(strat == BTGreaterStrategyNumber ||
strat == BTGreaterEqualStrategyNumber) )
{ {
strat = _bt_getstrat(rel, 1, so->keyData[0].sk_procedure); nKeyIs[keysCount++] = i;
strat_total = strat;
if (strat == BTLessStrategyNumber || if (strat == BTGreaterStrategyNumber)
strat == BTLessEqualStrategyNumber) break;
; continue;
else }
nKeyIndex = 0;
} }
if (nKeyIndex < 0) if (!keysCount)
scan->scanFromEnd = true; scan->scanFromEnd = true;
} }
else else
...@@ -784,7 +807,11 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) ...@@ -784,7 +807,11 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
/* if we just need to walk down one edge of the tree, do that */ /* if we just need to walk down one edge of the tree, do that */
if (scan->scanFromEnd) if (scan->scanFromEnd)
{
if (nKeyIs)
pfree(nKeyIs);
return _bt_endpoint(scan, dir); return _bt_endpoint(scan, dir);
}
itupdesc = RelationGetDescr(rel); itupdesc = RelationGetDescr(rel);
current = &(scan->currentItemData); current = &(scan->currentItemData);
...@@ -796,16 +823,24 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) ...@@ -796,16 +823,24 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
* at the right place in the scan. * at the right place in the scan.
*/ */
/* _bt_orderkeys disallows it, but it's place to add some code latter */ /* _bt_orderkeys disallows it, but it's place to add some code latter */
if (so->keyData[0].sk_flags & SK_ISNULL) scankeys = (ScanKey)palloc(keysCount*sizeof(ScanKeyData));
for (i=0; i < keysCount; i++)
{
j = nKeyIs[i];
if (so->keyData[j].sk_flags & SK_ISNULL)
{ {
pfree(nKeyIs);
pfree(scankeys);
elog(ERROR, "_bt_first: btree doesn't support is(not)null, yet"); elog(ERROR, "_bt_first: btree doesn't support is(not)null, yet");
return (RetrieveIndexResult) NULL; return ((RetrieveIndexResult) NULL);
} }
proc = index_getprocid(rel, 1, BTORDER_PROC); proc = index_getprocid(rel, i+1, BTORDER_PROC);
ScanKeyEntryInitialize(&skdata, so->keyData[nKeyIndex].sk_flags, ScanKeyEntryInitialize(scankeys+i, so->keyData[j].sk_flags,
1, proc, so->keyData[nKeyIndex].sk_argument); i+1, proc, so->keyData[j].sk_argument);
}
if (nKeyIs) pfree(nKeyIs);
stack = _bt_search(rel, 1, &skdata, &buf); stack = _bt_search(rel, keysCount, scankeys, &buf);
_bt_freestack(stack); _bt_freestack(stack);
blkno = BufferGetBlockNumber(buf); blkno = BufferGetBlockNumber(buf);
...@@ -823,6 +858,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) ...@@ -823,6 +858,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
ItemPointerSetInvalid(current); ItemPointerSetInvalid(current);
so->btso_curbuf = InvalidBuffer; so->btso_curbuf = InvalidBuffer;
_bt_relbuf(rel, buf, BT_READ); _bt_relbuf(rel, buf, BT_READ);
pfree(scankeys);
return (RetrieveIndexResult) NULL; return (RetrieveIndexResult) NULL;
} }
maxoff = PageGetMaxOffsetNumber(page); maxoff = PageGetMaxOffsetNumber(page);
...@@ -835,7 +871,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) ...@@ -835,7 +871,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
*/ */
while (maxoff == P_HIKEY && !P_RIGHTMOST(pop) && while (maxoff == P_HIKEY && !P_RIGHTMOST(pop) &&
_bt_skeycmp(rel, 1, &skdata, page, _bt_skeycmp(rel, keysCount, scankeys, page,
PageGetItemId(page, P_HIKEY), PageGetItemId(page, P_HIKEY),
BTGreaterEqualStrategyNumber)) BTGreaterEqualStrategyNumber))
{ {
...@@ -849,6 +885,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) ...@@ -849,6 +885,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
ItemPointerSetInvalid(current); ItemPointerSetInvalid(current);
so->btso_curbuf = InvalidBuffer; so->btso_curbuf = InvalidBuffer;
_bt_relbuf(rel, buf, BT_READ); _bt_relbuf(rel, buf, BT_READ);
pfree(scankeys);
return (RetrieveIndexResult) NULL; return (RetrieveIndexResult) NULL;
} }
maxoff = PageGetMaxOffsetNumber(page); maxoff = PageGetMaxOffsetNumber(page);
...@@ -857,7 +894,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) ...@@ -857,7 +894,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
/* find the nearest match to the manufactured scan key on the page */ /* find the nearest match to the manufactured scan key on the page */
offnum = _bt_binsrch(rel, buf, 1, &skdata, BT_DESCENT); offnum = _bt_binsrch(rel, buf, keysCount, scankeys, BT_DESCENT);
if (offnum > maxoff) if (offnum > maxoff)
{ {
...@@ -872,12 +909,11 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) ...@@ -872,12 +909,11 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
* we're looking for minus the value we're looking at in the index. * we're looking for minus the value we're looking at in the index.
*/ */
result = _bt_compare(rel, itupdesc, page, 1, &skdata, offnum); result = _bt_compare(rel, itupdesc, page, keysCount, scankeys, offnum);
/* it's yet other place to add some code latter for is(not)null */ /* it's yet other place to add some code latter for is(not)null */
strat = _bt_getstrat(rel, 1, so->keyData[nKeyIndex].sk_procedure); strat = strat_total;
switch (strat) switch (strat)
{ {
case BTLessStrategyNumber: case BTLessStrategyNumber:
...@@ -890,7 +926,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) ...@@ -890,7 +926,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
offnum = ItemPointerGetOffsetNumber(current); offnum = ItemPointerGetOffsetNumber(current);
page = BufferGetPage(buf); page = BufferGetPage(buf);
result = _bt_compare(rel, itupdesc, page, 1, &skdata, offnum); result = _bt_compare(rel, itupdesc, page, keysCount, scankeys, offnum);
} while (result <= 0); } while (result <= 0);
} }
...@@ -906,12 +942,11 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) ...@@ -906,12 +942,11 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
offnum = ItemPointerGetOffsetNumber(current); offnum = ItemPointerGetOffsetNumber(current);
page = BufferGetPage(buf); page = BufferGetPage(buf);
result = _bt_compare(rel, itupdesc, page, 1, &skdata, offnum); result = _bt_compare(rel, itupdesc, page, keysCount, scankeys, offnum);
} while (result >= 0); } while (result >= 0);
}
if (result < 0) if (result < 0)
_bt_twostep(scan, &buf, BackwardScanDirection); _bt_twostep(scan, &buf, BackwardScanDirection);
}
break; break;
case BTEqualStrategyNumber: case BTEqualStrategyNumber:
...@@ -920,6 +955,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) ...@@ -920,6 +955,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
_bt_relbuf(scan->relation, buf, BT_READ); _bt_relbuf(scan->relation, buf, BT_READ);
so->btso_curbuf = InvalidBuffer; so->btso_curbuf = InvalidBuffer;
ItemPointerSetInvalid(&(scan->currentItemData)); ItemPointerSetInvalid(&(scan->currentItemData));
pfree(scankeys);
return (RetrieveIndexResult) NULL; return (RetrieveIndexResult) NULL;
} }
else if (ScanDirectionIsBackward(dir)) else if (ScanDirectionIsBackward(dir))
...@@ -931,7 +967,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) ...@@ -931,7 +967,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
offnum = ItemPointerGetOffsetNumber(current); offnum = ItemPointerGetOffsetNumber(current);
page = BufferGetPage(buf); page = BufferGetPage(buf);
result = _bt_compare(rel, itupdesc, page, 1, &skdata, offnum); result = _bt_compare(rel, itupdesc, page, keysCount, scankeys, offnum);
} while (result == 0); } while (result == 0);
if (result < 0) if (result < 0)
...@@ -950,6 +986,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) ...@@ -950,6 +986,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
_bt_relbuf(scan->relation, buf, BT_READ); _bt_relbuf(scan->relation, buf, BT_READ);
so->btso_curbuf = InvalidBuffer; so->btso_curbuf = InvalidBuffer;
ItemPointerSetInvalid(&(scan->currentItemData)); ItemPointerSetInvalid(&(scan->currentItemData));
pfree(scankeys);
return (RetrieveIndexResult) NULL; return (RetrieveIndexResult) NULL;
} }
} }
...@@ -974,7 +1011,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) ...@@ -974,7 +1011,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
page = BufferGetPage(buf); page = BufferGetPage(buf);
offnum = ItemPointerGetOffsetNumber(current); offnum = ItemPointerGetOffsetNumber(current);
result = _bt_compare(rel, itupdesc, page, 1, &skdata, offnum); result = _bt_compare(rel, itupdesc, page, keysCount, scankeys, offnum);
} while (result < 0); } while (result < 0);
if (result > 0) if (result > 0)
...@@ -993,12 +1030,13 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) ...@@ -993,12 +1030,13 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
offnum = ItemPointerGetOffsetNumber(current); offnum = ItemPointerGetOffsetNumber(current);
page = BufferGetPage(buf); page = BufferGetPage(buf);
result = _bt_compare(rel, itupdesc, page, 1, &skdata, offnum); result = _bt_compare(rel, itupdesc, page, keysCount, scankeys, offnum);
} while (result >= 0); } while (result >= 0);
} }
break; break;
} }
pfree(scankeys);
/* okay, current item pointer for the scan is right */ /* okay, current item pointer for the scan is right */
offnum = ItemPointerGetOffsetNumber(current); offnum = ItemPointerGetOffsetNumber(current);
page = BufferGetPage(buf); page = BufferGetPage(buf);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.32 1999/07/17 20:16:43 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.33 1999/09/27 18:20:21 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -101,6 +101,7 @@ _bt_orderkeys(Relation relation, BTScanOpaque so) ...@@ -101,6 +101,7 @@ _bt_orderkeys(Relation relation, BTScanOpaque so)
uint16 numberOfKeys = so->numberOfKeys; uint16 numberOfKeys = so->numberOfKeys;
uint16 new_numberOfKeys = 0; uint16 new_numberOfKeys = 0;
AttrNumber attno = 1; AttrNumber attno = 1;
bool equalStrategyEnd, underEqualStrategy;
if (numberOfKeys < 1) if (numberOfKeys < 1)
return; return;
...@@ -136,6 +137,8 @@ _bt_orderkeys(Relation relation, BTScanOpaque so) ...@@ -136,6 +137,8 @@ _bt_orderkeys(Relation relation, BTScanOpaque so)
for (j = 0; j <= BTMaxStrategyNumber; j++) for (j = 0; j <= BTMaxStrategyNumber; j++)
init[j] = 0; init[j] = 0;
equalStrategyEnd = false;
underEqualStrategy = true;
/* check each key passed in */ /* check each key passed in */
for (i = 0;;) for (i = 0;;)
{ {
...@@ -150,6 +153,7 @@ _bt_orderkeys(Relation relation, BTScanOpaque so) ...@@ -150,6 +153,7 @@ _bt_orderkeys(Relation relation, BTScanOpaque so)
if (cur->sk_attno != attno + 1 && i < numberOfKeys) if (cur->sk_attno != attno + 1 && i < numberOfKeys)
elog(ERROR, "_bt_orderkeys: key(s) for attribute %d missed", attno + 1); elog(ERROR, "_bt_orderkeys: key(s) for attribute %d missed", attno + 1);
underEqualStrategy = (!equalStrategyEnd);
/* /*
* If = has been specified, no other key will be used. In case * If = has been specified, no other key will be used. In case
* of key < 2 && key == 1 and so on we have to set qual_ok to * of key < 2 && key == 1 and so on we have to set qual_ok to
...@@ -175,6 +179,8 @@ _bt_orderkeys(Relation relation, BTScanOpaque so) ...@@ -175,6 +179,8 @@ _bt_orderkeys(Relation relation, BTScanOpaque so)
init[BTGreaterEqualStrategyNumber - 1] = 0; init[BTGreaterEqualStrategyNumber - 1] = 0;
init[BTGreaterStrategyNumber - 1] = 0; init[BTGreaterStrategyNumber - 1] = 0;
} }
else
equalStrategyEnd = true;
/* only one of <, <= */ /* only one of <, <= */
if (init[BTLessStrategyNumber - 1] if (init[BTLessStrategyNumber - 1]
...@@ -223,7 +229,7 @@ _bt_orderkeys(Relation relation, BTScanOpaque so) ...@@ -223,7 +229,7 @@ _bt_orderkeys(Relation relation, BTScanOpaque so)
if (init[j]) if (init[j])
key[new_numberOfKeys++] = xform[j]; key[new_numberOfKeys++] = xform[j];
if (attno == 1) if (underEqualStrategy)
so->numberOfFirstKeys = new_numberOfKeys; so->numberOfFirstKeys = new_numberOfKeys;
if (i == numberOfKeys) if (i == numberOfKeys)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment