mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-18 10:21:03 +03:00
Further enhancements to the min/max optimization of
[/info/b8ba2f17f938c035|check-in b8ba2f17f938c035] to fix the performance regression identified by [forum:/forumpost/623f571482|forum post 623f571482]. FossilOrigin-Name: 188772a1dbaf066fbddd39c718fdd87478b19a920622f4640bcb79d4ef065331
This commit is contained in:
@@ -6773,7 +6773,7 @@ int sqlite3Select(
|
||||
/* End of the loop
|
||||
*/
|
||||
if( groupBySort ){
|
||||
sqlite3VdbeAddOp2(v, OP_SorterNext, pAggInfo->sortingIdx, addrTopOfLoop);
|
||||
sqlite3VdbeAddOp2(v, OP_SorterNext, pAggInfo->sortingIdx,addrTopOfLoop);
|
||||
VdbeCoverage(v);
|
||||
}else{
|
||||
sqlite3WhereEnd(pWInfo);
|
||||
@@ -6885,7 +6885,6 @@ int sqlite3Select(
|
||||
explainSimpleCount(pParse, pTab, pBest);
|
||||
}else{
|
||||
int regAcc = 0; /* "populate accumulators" flag */
|
||||
int addrSkip;
|
||||
|
||||
/* If there are accumulator registers but no min() or max() functions
|
||||
** without FILTER clauses, allocate register regAcc. Register regAcc
|
||||
@@ -6934,9 +6933,8 @@ int sqlite3Select(
|
||||
}
|
||||
updateAccumulator(pParse, regAcc, pAggInfo);
|
||||
if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc);
|
||||
addrSkip = sqlite3WhereOrderByLimitOptLabel(pWInfo);
|
||||
if( addrSkip!=sqlite3WhereContinueLabel(pWInfo) ){
|
||||
sqlite3VdbeGoto(v, addrSkip);
|
||||
if( minMaxFlag ){
|
||||
sqlite3WhereMinMaxOptEarlyOut(v, pWInfo);
|
||||
}
|
||||
sqlite3WhereEnd(pWInfo);
|
||||
finalizeAggFunctions(pParse, pAggInfo);
|
||||
|
||||
@@ -4341,6 +4341,7 @@ LogEst sqlite3WhereOutputRowCount(WhereInfo*);
|
||||
int sqlite3WhereIsDistinct(WhereInfo*);
|
||||
int sqlite3WhereIsOrdered(WhereInfo*);
|
||||
int sqlite3WhereOrderByLimitOptLabel(WhereInfo*);
|
||||
void sqlite3WhereMinMaxOptEarlyOut(Vdbe*,WhereInfo*);
|
||||
int sqlite3WhereIsSorted(WhereInfo*);
|
||||
int sqlite3WhereContinueLabel(WhereInfo*);
|
||||
int sqlite3WhereBreakLabel(WhereInfo*);
|
||||
|
||||
23
src/where.c
23
src/where.c
@@ -99,6 +99,29 @@ int sqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){
|
||||
return pInner->addrNxt;
|
||||
}
|
||||
|
||||
/*
|
||||
** While generating code for the min/max optimization, after handling
|
||||
** the aggregate-step call to min() or max(), check to see if any
|
||||
** additional looping is required. If the output order is such that
|
||||
** we are certain that the correct answer has already been found, then
|
||||
** code an OP_Goto to by pass subsequent processing.
|
||||
**
|
||||
** Any extra OP_Goto that is coded here is an optimization. The
|
||||
** correct answer should be obtained regardless. This OP_Goto just
|
||||
** makes the answer appear faster.
|
||||
*/
|
||||
void sqlite3WhereMinMaxOptEarlyOut(Vdbe *v, WhereInfo *pWInfo){
|
||||
WhereLevel *pInner;
|
||||
if( !pWInfo->bOrderedInnerLoop ) return;
|
||||
if( pWInfo->nOBSat==0 ) return;
|
||||
pInner = &pWInfo->a[pWInfo->nLevel-1];
|
||||
if( (pInner->pWLoop->wsFlags & WHERE_COLUMN_IN)==0 ){
|
||||
sqlite3VdbeGoto(v, pWInfo->iBreak);
|
||||
}else if( pInner->addrNxt!=pWInfo->iContinue ){
|
||||
sqlite3VdbeGoto(v, pInner->addrNxt);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the VDBE address or label to jump to in order to continue
|
||||
** immediately with the next row of a WHERE clause.
|
||||
|
||||
Reference in New Issue
Block a user