diff options
author | drh <drh@noemail.net> | 2020-10-22 18:50:30 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2020-10-22 18:50:30 +0000 |
commit | beb22d086bae43a3e21ee140af3a9c8e369939d9 (patch) | |
tree | ce05e1e56d0266eefdc58de62f37fe6139a75b2d /src | |
parent | 672f07c642fad9ad76b1a8cd1c1d196d0286ffc4 (diff) | |
parent | 461ff3594b86506d4d4c4294be336d5da2757cd8 (diff) | |
download | sqlite-beb22d086bae43a3e21ee140af3a9c8e369939d9.tar.gz sqlite-beb22d086bae43a3e21ee140af3a9c8e369939d9.zip |
Minor tweaks to query planning weights so that when STAT4 is enabled
and functioning, a full table scan is more likely to be selected if
that seems like the fastest solution. Only do this when STAT4 info
is available because an error has a large potential downside.
FossilOrigin-Name: 0e7e113d9f2c929c1f8a85e2cfad8e2e60f0e8770212b5e5320fb2a2c42911f8
Diffstat (limited to 'src')
-rw-r--r-- | src/analyze.c | 1 | ||||
-rw-r--r-- | src/sqliteInt.h | 1 | ||||
-rw-r--r-- | src/where.c | 17 |
3 files changed, 18 insertions, 1 deletions
diff --git a/src/analyze.c b/src/analyze.c index 9a9de991d..dc77220a5 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1772,6 +1772,7 @@ static int loadStatTbl( } pSpace = (tRowcnt*)&pIdx->aSample[nSample]; pIdx->aAvgEq = pSpace; pSpace += nIdxCol; + pIdx->pTable->tabFlags |= TF_HasStat4; for(i=0; i<nSample; i++){ pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol; pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index ec832eca6..467062277 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2187,6 +2187,7 @@ struct Table { #define TF_OOOHidden 0x0400 /* Out-of-Order hidden columns */ #define TF_HasNotNull 0x0800 /* Contains NOT NULL constraints */ #define TF_Shadow 0x1000 /* True for a shadow table */ +#define TF_HasStat4 0x2000 /* STAT4 info available for this table */ /* ** Test to see whether or not a table is a virtual table. This is diff --git a/src/where.c b/src/where.c index ec00482e9..9f35dce02 100644 --- a/src/where.c +++ b/src/where.c @@ -3042,8 +3042,23 @@ static int whereLoopAddBtree( /* Full table scan */ pNew->iSortIdx = b ? iSortIdx : 0; - /* TUNING: Cost of full table scan is (N*3.0). */ + /* TUNING: Cost of full table scan is 3.0*N. The 3.0 factor is an + ** extra cost designed to discourage the use of full table scans, + ** since index lookups have better worst-case performance if our + ** stat guesses are wrong. Reduce the 3.0 penalty slightly + ** (to 2.75) if we have valid STAT4 information for the table. + ** At 2.75, a full table scan is preferred over using an index on + ** a column with just two distinct values where each value has about + ** an equal number of appearances. Without STAT4 data, we still want + ** to use an index in that case, since the constraint might be for + ** the scarcer of the two values, and in that case an index lookup is + ** better. + */ +#ifdef SQLITE_ENABLE_STAT4 + pNew->rRun = rSize + 16 - 2*((pTab->tabFlags & TF_HasStat4)!=0); +#else pNew->rRun = rSize + 16; +#endif ApplyCostMultiplier(pNew->rRun, pTab->costMult); whereLoopOutputAdjust(pWC, pNew, rSize); rc = whereLoopInsert(pBuilder, pNew); |