1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-12 13:01:09 +03:00

When estimating the cost of an index scan, factor in the cost savings of

being able to use the index to evaluate some WHERE clause terms without
having to do a table lookup.

FossilOrigin-Name: a59b5622f7cc6e502d71aabc12c053582cd03609
This commit is contained in:
drh
2016-07-27 18:27:02 +00:00
parent 2900a6222f
commit 2409f8a112
5 changed files with 96 additions and 13 deletions

View File

@@ -3965,6 +3965,61 @@ int sqlite3ExprImpliesExpr(Expr *pE1, Expr *pE2, int iTab){
return 0;
}
/*
** An instance of the following structure is used by the tree walker
** to determine if an expression can be evaluated by reference to the
** index only, without having to do a search for the corresponding
** table entry. The IdxCover.pIdx field is the index. IdxCover.iCur
** is the cursor for the table.
*/
struct IdxCover {
Index *pIdx; /* The index to be tested for coverage */
int iCur; /* Cursor number for the table corresponding to the index */
};
/*
** Check to see if there are references to columns in table
** pWalker->u.pIdxCover->iCur can be satisfied using the index
** pWalker->u.pIdxCover->pIdx.
*/
static int exprIdxCover(Walker *pWalker, Expr *pExpr){
if( pExpr->op==TK_COLUMN
&& pExpr->iTable==pWalker->u.pIdxCover->iCur
&& sqlite3ColumnOfIndex(pWalker->u.pIdxCover->pIdx, pExpr->iColumn)<0
){
pWalker->eCode = 1;
return WRC_Abort;
}
return WRC_Continue;
}
/*
** Determine if an index on table iCur that contains the columns in
** Bitmask m will cover the expression pExpr. Return true if the index
** does cover the expression and false if the expression references
** table columns that are not found in the index.
**
** An index covering an expression means that the expression can be
** evaluated using only the index and without having to lookup the
** corresponding table entry.
*/
int sqlite3ExprCoveredByIndex(
Expr *pExpr, /* The index to be tested */
int iCur, /* The cursor number for the corresponding table */
Index *pIdx /* The index that might be used for coverage */
){
Walker w;
struct IdxCover xcov;
memset(&w, 0, sizeof(w));
xcov.iCur = iCur;
xcov.pIdx = pIdx;
w.xExprCallback = exprIdxCover;
w.u.pIdxCover = &xcov;
sqlite3WalkExpr(&w, pExpr);
return !w.eCode;
}
/*
** An instance of the following structure is used by the tree walker
** to count references to table columns in the arguments of an