aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2020-10-22 18:50:30 +0000
committerdrh <drh@noemail.net>2020-10-22 18:50:30 +0000
commitbeb22d086bae43a3e21ee140af3a9c8e369939d9 (patch)
treece05e1e56d0266eefdc58de62f37fe6139a75b2d /src
parent672f07c642fad9ad76b1a8cd1c1d196d0286ffc4 (diff)
parent461ff3594b86506d4d4c4294be336d5da2757cd8 (diff)
downloadsqlite-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.c1
-rw-r--r--src/sqliteInt.h1
-rw-r--r--src/where.c17
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);