mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-18 10:21:03 +03:00
When the estimated cost to do a sort overwhelms the estimated cost to do
individual table lookups, make sure that the table lookup costs are still taken into consideration when selecting the lookup algorithm. FossilOrigin-Name: ec5d84ba69c100d9565425ed74040a49e410ea03
This commit is contained in:
37
src/where.c
37
src/where.c
@@ -5424,6 +5424,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
LogEst rCost; /* Cost of a path */
|
||||
LogEst nOut; /* Number of outputs */
|
||||
LogEst mxCost = 0; /* Maximum cost of a set of paths */
|
||||
LogEst mxOut = 0; /* nOut value for maximum cost path */
|
||||
int nTo, nFrom; /* Number of valid entries in aTo[] and aFrom[] */
|
||||
WherePath *aFrom; /* All nFrom paths at the previous level */
|
||||
WherePath *aTo; /* The nTo best paths at the current level */
|
||||
@@ -5441,7 +5442,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
** For joins of 3 or more tables, track the 10 best paths */
|
||||
mxChoice = (nLoop<=1) ? 1 : (nLoop==2 ? 5 : 10);
|
||||
assert( nLoop<=pWInfo->pTabList->nSrc );
|
||||
WHERETRACE(0x002, ("---- begin solver\n"));
|
||||
WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d)\n", nRowEst));
|
||||
|
||||
/* Allocate and initialize space for aTo and aFrom */
|
||||
ii = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2;
|
||||
@@ -5529,7 +5530,13 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
}else{
|
||||
revMask = pFrom->revLoop;
|
||||
}
|
||||
/* Check to see if pWLoop should be added to the mxChoice best so far */
|
||||
/* Check to see if pWLoop should be added to the set of
|
||||
** mxChoice best-so-far paths.
|
||||
**
|
||||
** First look for an existing path among best-so-far paths
|
||||
** that covers the same set of loops and has the same isOrdered
|
||||
** setting as the current path candidate.
|
||||
*/
|
||||
for(jj=0, pTo=aTo; jj<nTo; jj++, pTo++){
|
||||
if( pTo->maskLoop==maskNew
|
||||
&& ((pTo->isOrdered^isOrdered)&80)==0
|
||||
@@ -5539,7 +5546,14 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
}
|
||||
}
|
||||
if( jj>=nTo ){
|
||||
if( nTo>=mxChoice && rCost>=mxCost ){
|
||||
/* None of the existing best-so-far paths match the candidate. */
|
||||
if( nTo>=mxChoice && rCost==mxCost ) printf("nOut=%d mxOut=%d\n", nOut, mxOut);
|
||||
if( nTo>=mxChoice
|
||||
&& (rCost>mxCost || (rCost==mxCost && nOut>=mxOut))
|
||||
){
|
||||
/* The current candidate is no better than any of the mxChoice
|
||||
** paths currently in the best-so-far buffer. So discard
|
||||
** this candidate as not viable. */
|
||||
#ifdef WHERETRACE_ENABLED /* 0x4 */
|
||||
if( sqlite3WhereTrace&0x4 ){
|
||||
sqlite3DebugPrintf("Skip %s cost=%-3d,%3d order=%c\n",
|
||||
@@ -5549,7 +5563,8 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
/* Add a new Path to the aTo[] set */
|
||||
/* If we reach this points it means that the new candidate path
|
||||
** needs to be added to the set of best-so-far paths. */
|
||||
if( nTo<mxChoice ){
|
||||
/* Increase the size of the aTo set by one */
|
||||
jj = nTo++;
|
||||
@@ -5566,7 +5581,11 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
}
|
||||
#endif
|
||||
}else{
|
||||
if( pTo->rCost<=rCost ){
|
||||
/* Control reaches here if best-so-far path pTo=aTo[jj] covers the
|
||||
** same set of loops and has the sam isOrdered setting as the
|
||||
** candidate path. Check to see if the candidate should replace
|
||||
** pTo or if the candidate should be skipped */
|
||||
if( pTo->rCost<rCost || (pTo->rCost==rCost && pTo->nRow<=nOut) ){
|
||||
#ifdef WHERETRACE_ENABLED /* 0x4 */
|
||||
if( sqlite3WhereTrace&0x4 ){
|
||||
sqlite3DebugPrintf(
|
||||
@@ -5578,11 +5597,13 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?');
|
||||
}
|
||||
#endif
|
||||
/* Discard the candidate path from further consideration */
|
||||
testcase( pTo->rCost==rCost );
|
||||
continue;
|
||||
}
|
||||
testcase( pTo->rCost==rCost+1 );
|
||||
/* A new and better score for a previously created equivalent path */
|
||||
/* Control reaches here if the candidate path is better than the
|
||||
** pTo path. Replace pTo with the candidate. */
|
||||
#ifdef WHERETRACE_ENABLED /* 0x4 */
|
||||
if( sqlite3WhereTrace&0x4 ){
|
||||
sqlite3DebugPrintf(
|
||||
@@ -5606,9 +5627,11 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
if( nTo>=mxChoice ){
|
||||
mxI = 0;
|
||||
mxCost = aTo[0].rCost;
|
||||
mxOut = aTo[0].nRow;
|
||||
for(jj=1, pTo=&aTo[1]; jj<mxChoice; jj++, pTo++){
|
||||
if( pTo->rCost>mxCost ){
|
||||
if( pTo->rCost>mxCost || (pTo->rCost==mxCost && pTo->nRow>mxOut) ){
|
||||
mxCost = pTo->rCost;
|
||||
mxOut = pTo->nRow;
|
||||
mxI = jj;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user