diff options
author | drh <> | 2024-05-28 00:16:52 +0000 |
---|---|---|
committer | drh <> | 2024-05-28 00:16:52 +0000 |
commit | 18970dac182b703f61422a23a921cef436f9ce7f (patch) | |
tree | 8b1020c56e802eed970e471b24b7cb629ee5fc53 /src | |
parent | 38af12523865b98cdc64fa518fc85ea754697e09 (diff) | |
parent | b23f92b2867e89ddecc4f4ccb6dc406e4d5ab726 (diff) | |
download | sqlite-18970dac182b703f61422a23a921cef436f9ce7f.tar.gz sqlite-18970dac182b703f61422a23a921cef436f9ce7f.zip |
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
Diffstat (limited to 'src')
-rw-r--r-- | src/where.c | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/src/where.c b/src/where.c index 9ef48fb33..980047947 100644 --- a/src/where.c +++ b/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 |