mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Improve the automatic-index decision such that no attempt is made to create
an automatic index on a column that is known to be non-selective because if its use in other indexes that have been analyzed. See [src:/tktview/8ff324e120|ticket 8ff324e120] and [forum:/forumpost/b21c2101a559be0a|forum post b21c2101a559be0a]. FossilOrigin-Name: 2a7603c327d11d5e6bc4d40c29151fea544d650f51200ff76efb921adb0c38df
This commit is contained in:
43
src/where.c
43
src/where.c
@ -840,6 +840,40 @@ static int constraintCompatibleWithOuterJoin(
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
|
||||
/*
|
||||
** Return true if column iCol of table pTab seem like it might be a
|
||||
** good column to use as part of a query-time index.
|
||||
**
|
||||
** Current algorithm (subject to improvement!):
|
||||
**
|
||||
** 1. If iCol is already the left-most column of some other index,
|
||||
** then return false.
|
||||
**
|
||||
** 2. If iCol is part of an existing index that has an aiRowLogEst of
|
||||
** more than 20, then return false.
|
||||
**
|
||||
** 3. If no disqualifying conditions above are found, return true.
|
||||
*/
|
||||
static SQLITE_NOINLINE int columnIsGoodIndexCandidate(
|
||||
const Table *pTab,
|
||||
int iCol
|
||||
){
|
||||
const Index *pIdx;
|
||||
for(pIdx = pTab->pIndex; pIdx!=0; pIdx=pIdx->pNext){
|
||||
int j;
|
||||
for(j=0; j<pIdx->nKeyCol; j++){
|
||||
if( pIdx->aiColumn[j]==iCol ){
|
||||
if( j==0 ) return 0;
|
||||
if( pIdx->hasStat1 && pIdx->aiRowLogEst[j+1]>20 ) return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
|
||||
|
||||
|
||||
|
||||
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
|
||||
@ -854,6 +888,8 @@ static int termCanDriveIndex(
|
||||
const Bitmask notReady /* Tables in outer loops of the join */
|
||||
){
|
||||
char aff;
|
||||
int leftCol;
|
||||
|
||||
if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
|
||||
if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0;
|
||||
assert( (pSrc->fg.jointype & JT_RIGHT)==0 );
|
||||
@ -864,11 +900,12 @@ static int termCanDriveIndex(
|
||||
}
|
||||
if( (pTerm->prereqRight & notReady)!=0 ) return 0;
|
||||
assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
|
||||
if( pTerm->u.x.leftColumn<0 ) return 0;
|
||||
aff = pSrc->pTab->aCol[pTerm->u.x.leftColumn].affinity;
|
||||
leftCol = pTerm->u.x.leftColumn;
|
||||
if( leftCol<0 ) return 0;
|
||||
aff = pSrc->pTab->aCol[leftCol].affinity;
|
||||
if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0;
|
||||
testcase( pTerm->pExpr->op==TK_IS );
|
||||
return 1;
|
||||
return columnIsGoodIndexCandidate(pSrc->pTab, leftCol);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user