aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <>2024-05-28 00:16:52 +0000
committerdrh <>2024-05-28 00:16:52 +0000
commit18970dac182b703f61422a23a921cef436f9ce7f (patch)
tree8b1020c56e802eed970e471b24b7cb629ee5fc53 /src
parent38af12523865b98cdc64fa518fc85ea754697e09 (diff)
parentb23f92b2867e89ddecc4f4ccb6dc406e4d5ab726 (diff)
downloadsqlite-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.c43
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