1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-18 10:21:03 +03:00

Try to run all Bloom filters before any Seeks. This gives a small performance

gain on the Star-Schema Benchmark.

FossilOrigin-Name: 5be2470f8755ef454f813c880e659bdbf82f2396be9320cf3079cd4ca8e81a19
This commit is contained in:
drh
2021-12-05 00:45:55 +00:00
parent fecbf0a179
commit 35685d3e5e
5 changed files with 71 additions and 12 deletions

View File

@@ -1304,6 +1304,60 @@ static void whereApplyPartialIndexConstraints(
}
}
#if 1
/*
** An OP_Filter has just been generated, but the corresponding
** index search has not yet been performed. This routine
** checks to see if there are additional WHERE_BLOOMFILTER in
** inner loops that can be evaluated right away, and if there are,
** it evaluates those filters as well, and removes the WHERE_BLOOMFILTER
** tag.
*/
static SQLITE_NOINLINE void filterPullDown(
Parse *pParse, /* Parsing context */
WhereInfo *pWInfo, /* Complete information about the WHERE clause */
int iLevel, /* Which level of pWInfo->a[] should be coded */
int addrNxt, /* Jump here to bypass inner loops */
Bitmask notReady /* Loops that are not ready */
){
while( ++iLevel < pWInfo->nLevel ){
WhereLevel *pLevel = &pWInfo->a[iLevel];
WhereLoop *pLoop = pLevel->pWLoop;
if( (pLoop->wsFlags & WHERE_BLOOMFILTER)==0 ) continue;
if( pLoop->prereq & notReady ) continue;
sqlite3ConstructBloomFilter(pWInfo, &pWInfo->a[iLevel]);
if( pLoop->wsFlags & WHERE_IPK ){
WhereTerm *pTerm = pLoop->aLTerm[0];
int r1, regRowid;
assert( pTerm!=0 );
assert( pTerm->pExpr!=0 );
testcase( pTerm->wtFlags & TERM_VIRTUAL );
r1 = sqlite3GetTempReg(pParse);
regRowid = codeEqualityTerm(pParse, pTerm, pLevel, 0, 0, r1);
if( regRowid!=r1 ) sqlite3ReleaseTempReg(pParse, r1);
sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter,
addrNxt, regRowid, 1);
VdbeCoverage(pParse->pVdbe);
}else{
u16 nEq = pLoop->u.btree.nEq;
int r1;
char *zStartAff;
assert( pLoop->wsFlags & WHERE_INDEXED );
r1 = codeAllEqualityTerms(pParse,pLevel,0,0,&zStartAff);
codeApplyAffinity(pParse, r1, nEq, zStartAff);
sqlite3DbFree(pParse->db, zStartAff);
sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter,
addrNxt, r1, nEq);
VdbeCoverage(pParse->pVdbe);
}
pLoop->wsFlags &= ~WHERE_BLOOMFILTER;
}
}
#else
#define filterPullDown(A,B,C,D,E)
#endif
/*
** Generate code for the start of the iLevel-th loop in the WHERE clause
** implementation described by pWInfo.
@@ -1518,6 +1572,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
sqlite3VdbeAddOp4Int(v, OP_Filter, pLevel->regFilter, addrNxt,
iRowidReg, 1);
VdbeCoverage(v);
filterPullDown(pParse, pWInfo, iLevel, addrNxt, notReady);
}
sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg);
VdbeCoverage(v);
@@ -1848,6 +1903,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
sqlite3VdbeAddOp4Int(v, OP_Filter, pLevel->regFilter, addrNxt,
regBase, nEq);
VdbeCoverage(v);
filterPullDown(pParse, pWInfo, iLevel, addrNxt, notReady);
}
op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];