Compare commits

...

1 Commits

Author SHA1 Message Date
drh a161c222a6 Try to remember statistics from ANALYZE using LogEst instead of u64.
FossilOrigin-Name: 8e78557a40a6b97009852f5b72e68d6483fb00fc
2013-10-07 16:53:50 +00:00
8 changed files with 90 additions and 87 deletions
+14 -11
View File
@@ -1,5 +1,5 @@
C Merge\sbug\sfixes\sfrom\strunk.
D 2013-10-07T10:48:06.076
C Try\sto\sremember\sstatistics\sfrom\sANALYZE\susing\sLogEst\sinstead\sof\su64.
D 2013-10-07T16:53:50.515
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -157,7 +157,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 2af0330bb1b601af7a7789bf7229675fd772a083
F src/analyze.c c27da55795a11d09bea74259782c3e11e9750534
F src/analyze.c 3994309c21b7324217cd32225b7abb5cb1bd1946
F src/attach.c 0a17c9364895316ca4f52d06a97a72c0af1ae8b3
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c 2f1987981139bd2f6d8c728d64bf09fb387443c3
@@ -166,7 +166,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c d5720cbb21ae56e7e5b07847e05e5b203818acac
F src/btree.h bfe0e8c5759b4ec77b0d18390064a6ef3cdffaaf
F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0
F src/build.c ea07ec35354cdcd017b128679391320220030336
F src/build.c 46bb89df0a204eb7154874f966f11d16a7fbced7
F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c
@@ -216,12 +216,12 @@ F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b
F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68
F src/resolve.c 7459801d02997b07e8b8da85ef255392ba1d022b
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
F src/select.c 13be733297f415b388444a2e296d23569cd83b8a
F src/select.c 19611e6da6646a1090164b29d6b23b7c8e7364ea
F src/shell.c 5ee50ca3e35453bbd6ccdf1bdd0f6bbe9738e9fb
F src/sqlite.h.in ec40aa958a270416fb04b4f72210357bf163d2c5
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
F src/sqliteInt.h 5dbfc960fb39dbb55ba16697f453b03cd759b04a
F src/sqliteInt.h a5fa87b540662fb552ba81c0d4eeb368aebb5af7
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -275,7 +275,7 @@ F src/tokenize.c 70061085a51f2f4fc15ece94f32c03bcb78e63b2
F src/trigger.c ba0a883cd536b7dfdd4df3733001f5372a4299da
F src/update.c f5182157f5d0d0a97bc5f5e3c9bdba0dfbe08f08
F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918
F src/util.c 2f0c9b1f884d038eb90f48cf17042a88dc1629d3
F src/vacuum.c f313bc97123a4dd4bfd3f50a00c4d44c08a5b1b7
F src/vdbe.c 56e648f5ba9a91810caf216857adfed9039cd174
F src/vdbe.h 4f554b5627f26710c4c36d919110a3fc611ca5c4
@@ -290,7 +290,7 @@ F src/vtab.c 5a423b042eb1402ef77697d03d6a67378d97bc8d
F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74
F src/where.c 72c6c205e53ae72d2d235705bb2b040d70fff2e2
F src/where.c 7916e32a4d7f8cc891a08de09380ef519415d275
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
@@ -1121,7 +1121,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
P e9e932aa400f217e383cda9922fbde8a4356f57a 0aca31e1514b3df254c049b4251bcb199831681a
R 58571132dec54639078eadde66ba0889
P 1d7b2dc0eae70c0c0e523b715acf758bb4cfa9ac
R faf619696f929769ec0cefbeba9e27c2
T *branch * log-stats
T *sym-log-stats *
T -sym-row-size-est *
U drh
Z 412c711013eb3a5449cb7f9aec9f3c69
Z 72baf94bdfc7ce8839761e1732e0e2d4
+1 -1
View File
@@ -1 +1 @@
1d7b2dc0eae70c0c0e523b715acf758bb4cfa9ac
8e78557a40a6b97009852f5b72e68d6483fb00fc
+15 -15
View File
@@ -1252,13 +1252,13 @@ struct analysisInfo {
static void decodeIntArray(
char *zIntArray, /* String containing int array to decode */
int nOut, /* Number of slots in aOut[] */
tRowcnt *aOut, /* Store integers here */
LogEst *aOut, /* Convert values to 10*log2() and store here */
Index *pIndex /* Handle extra flags for this index, if not NULL */
){
char *z = zIntArray;
int c;
int i;
tRowcnt v;
u64 v;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( z==0 ) z = "";
@@ -1271,7 +1271,7 @@ static void decodeIntArray(
v = v*10 + c - '0';
z++;
}
aOut[i] = v;
aOut[i] = sqlite3LogEst(v);
if( *z==' ' ) z++;
}
if( pIndex ){
@@ -1368,10 +1368,10 @@ static void initAvgEq(Index *pIdx){
int iCol;
for(iCol=0; iCol<pIdx->nColumn; iCol++){
int i; /* Used to iterate through samples */
tRowcnt sumEq = 0; /* Sum of the nEq values */
tRowcnt nSum = 0; /* Number of terms contributing to sumEq */
tRowcnt avgEq = 0;
tRowcnt nDLt = pFinal->anDLt[iCol];
u64 sumEq = 0; /* Sum of the nEq values */
u64 nSum = 0; /* Number of terms contributing to sumEq */
u64 avgEq = 0;
u64 nDLt = sqlite3LogEstToInt(pFinal->anDLt[iCol]);
/* Set nSum to the number of distinct (iCol+1) field prefixes that
** occur in the stat4 table for this index before pFinal. Set
@@ -1380,15 +1380,15 @@ static void initAvgEq(Index *pIdx){
** prefixes). */
for(i=0; i<(pIdx->nSample-1); i++){
if( aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] ){
sumEq += aSample[i].anEq[iCol];
sumEq += sqlite3LogEstToInt(aSample[i].anEq[iCol]);
nSum++;
}
}
if( nDLt>nSum ){
avgEq = (pFinal->anLt[iCol] - sumEq)/(nDLt - nSum);
avgEq = (sqlite3LogEstToInt(pFinal->anLt[iCol]) - sumEq)/(nDLt - nSum);
}
if( avgEq==0 ) avgEq = 1;
pIdx->aAvgEq[iCol] = avgEq;
if( avgEq<=0 ) avgEq = 1;
pIdx->aAvgEq[iCol] = sqlite3LogEst(avgEq);
if( pIdx->nSampleCol==1 ) break;
}
}
@@ -1438,7 +1438,7 @@ static int loadStatTbl(
int nSample; /* Number of samples */
int nByte; /* Bytes of space required */
int i; /* Bytes of space required */
tRowcnt *pSpace;
LogEst *pSpace;
zIndex = (char *)sqlite3_column_text(pStmt, 0);
if( zIndex==0 ) continue;
@@ -1454,15 +1454,15 @@ static int loadStatTbl(
}
pIdx->nSampleCol = nIdxCol;
nByte = sizeof(IndexSample) * nSample;
nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample;
nByte += nAvgCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */
nByte += sizeof(LogEst) * nIdxCol * 3 * nSample;
nByte += nAvgCol * sizeof(LogEst); /* Space for Index.aAvgEq[] */
pIdx->aSample = sqlite3DbMallocZero(db, nByte);
if( pIdx->aSample==0 ){
sqlite3_finalize(pStmt);
return SQLITE_NOMEM;
}
pSpace = (tRowcnt*)&pIdx->aSample[nSample];
pSpace = (LogEst*)&pIdx->aSample[nSample];
pIdx->aAvgEq = pSpace; pSpace += nAvgCol;
for(i=0; i<nSample; i++){
pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol;
+11 -10
View File
@@ -879,7 +879,7 @@ void sqlite3StartTable(
pTable->iPKey = -1;
pTable->pSchema = db->aDb[iDb].pSchema;
pTable->nRef = 1;
pTable->nRowEst = 1000000;
pTable->nRowEst = 200;
assert( pParse->pNewTable==0 );
pParse->pNewTable = pTable;
@@ -2722,7 +2722,7 @@ Index *sqlite3CreateIndex(
nCol = pList->nExpr;
pIndex = sqlite3DbMallocZero(db,
ROUND8(sizeof(Index)) + /* Index structure */
ROUND8(sizeof(tRowcnt)*(nCol+1)) + /* Index.aiRowEst */
ROUND8(sizeof(LogEst)*(nCol+1)) + /* Index.aiRowEst */
sizeof(char *)*nCol + /* Index.azColl */
sizeof(int)*nCol + /* Index.aiColumn */
sizeof(u8)*nCol + /* Index.aSortOrder */
@@ -2733,9 +2733,9 @@ Index *sqlite3CreateIndex(
goto exit_create_index;
}
zExtra = (char*)pIndex;
pIndex->aiRowEst = (tRowcnt*)&zExtra[ROUND8(sizeof(Index))];
pIndex->aiRowEst = (LogEst*)&zExtra[ROUND8(sizeof(Index))];
pIndex->azColl = (char**)
((char*)pIndex->aiRowEst + ROUND8(sizeof(tRowcnt)*nCol+1));
((char*)pIndex->aiRowEst + ROUND8(sizeof(LogEst)*nCol+1));
assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowEst) );
assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) );
pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]);
@@ -3014,19 +3014,20 @@ exit_create_index:
** are based on typical values found in actual indices.
*/
void sqlite3DefaultRowEst(Index *pIdx){
tRowcnt *a = pIdx->aiRowEst;
LogEst *a = pIdx->aiRowEst;
int i;
tRowcnt n;
LogEst n;
assert( a!=0 );
a[0] = pIdx->pTable->nRowEst;
if( a[0]<10 ) a[0] = 10;
n = 10;
assert( 33==sqlite3LogEst(10) );
if( a[0]<34 ){ a[0] = 34; }
n = 34;
for(i=1; i<=pIdx->nColumn; i++){
a[i] = n;
if( n>5 ) n--;
if( n>24 ) n -= 2;
}
if( pIdx->onError!=OE_None ){
a[pIdx->nColumn] = 1;
a[pIdx->nColumn] = 0;
}
}
+2 -2
View File
@@ -1480,7 +1480,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
assert( db->lookaside.bEnabled==0 );
pTab->nRef = 1;
pTab->zName = 0;
pTab->nRowEst = 1000000;
pTab->nRowEst = 200;
selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSelect);
pTab->iPKey = -1;
@@ -3398,7 +3398,7 @@ static int selectExpander(Walker *pWalker, Select *p){
while( pSel->pPrior ){ pSel = pSel->pPrior; }
selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol);
pTab->iPKey = -1;
pTab->nRowEst = 1000000;
pTab->nRowEst = 200;
pTab->tabFlags |= TF_Ephemeral;
#endif
}else{
+6 -6
View File
@@ -1382,11 +1382,11 @@ struct Table {
#ifndef SQLITE_OMIT_CHECK
ExprList *pCheck; /* All CHECK constraints */
#endif
tRowcnt nRowEst; /* Estimated rows in table - from sqlite_stat1 table */
int tnum; /* Root BTree node for this table (see note above) */
i16 iPKey; /* If not negative, use aCol[iPKey] as the primary key */
i16 nCol; /* Number of columns in this table */
u16 nRef; /* Number of pointers to this Table */
LogEst nRowEst; /* Estimated number of rows in the table */
LogEst szTabRow; /* Estimated size of each table row in bytes */
u8 tabFlags; /* Mask of TF_* values */
u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */
@@ -1577,7 +1577,7 @@ struct UnpackedRecord {
struct Index {
char *zName; /* Name of this index */
int *aiColumn; /* Which columns are used by this index. 1st is 0 */
tRowcnt *aiRowEst; /* From ANALYZE: Est. rows selected by each column */
LogEst *aiRowEst; /* From ANALYZE: Est. rows selected by each column */
Table *pTable; /* The SQL table being indexed */
char *zColAff; /* String defining the affinity of each column */
Index *pNext; /* The next index associated with the same table */
@@ -1595,7 +1595,7 @@ struct Index {
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int nSample; /* Number of elements in aSample[] */
int nSampleCol; /* Size of IndexSample.anEq[] and so on */
tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */
LogEst *aAvgEq; /* Average nEq values for keys not in aSample */
IndexSample *aSample; /* Samples of the left-most key */
#endif
};
@@ -1608,9 +1608,9 @@ struct Index {
struct IndexSample {
void *p; /* Pointer to sampled record */
int n; /* Size of record in bytes */
tRowcnt *anEq; /* Est. number of rows where the key equals this sample */
tRowcnt *anLt; /* Est. number of rows where key is less than this sample */
tRowcnt *anDLt; /* Est. number of distinct keys less than this sample */
LogEst *anEq; /* Est. number of rows where the key equals this sample */
LogEst *anLt; /* Est. number of rows where key is less than this sample */
LogEst *anDLt; /* Est. number of distinct keys less than this sample */
};
/*
-1
View File
@@ -1213,7 +1213,6 @@ void sqlite3FileSuffix3(const char *zBaseFilename, char *z){
** Find (an approximate) sum of two LogEst values. This computation is
** not a simple "+" operator because LogEst is stored as a logarithmic
** value.
**
*/
LogEst sqlite3LogEstAdd(LogEst a, LogEst b){
static const unsigned char x[] = {
+41 -41
View File
@@ -2328,7 +2328,7 @@ static void whereKeyStats(
Index *pIdx, /* Index to consider domain of */
UnpackedRecord *pRec, /* Vector of values to consider */
int roundUp, /* Round up if true. Round down if false */
tRowcnt *aStat /* OUT: stats written here */
LogEst *aStat /* OUT: stats written here */
){
IndexSample *aSample = pIdx->aSample;
int iCol; /* Index of required stats in anEq[] etc. */
@@ -2381,15 +2381,16 @@ static void whereKeyStats(
aStat[0] = aSample[i].anLt[iCol];
aStat[1] = aSample[i].anEq[iCol];
}else{
tRowcnt iLower, iUpper, iGap;
LogEst iLower, iUpper, iGap;
if( i==0 ){
iLower = 0;
iUpper = aSample[0].anLt[iCol];
}else{
iUpper = i>=pIdx->nSample ? pIdx->aiRowEst[0] : aSample[i].anLt[iCol];
iLower = aSample[i-1].anEq[iCol] + aSample[i-1].anLt[iCol];
iLower = sqlite3LogEstAdd(aSample[i-1].anEq[iCol],
aSample[i-1].anLt[iCol]);
}
aStat[1] = (pIdx->nColumn>iCol ? pIdx->aAvgEq[iCol] : 1);
aStat[1] = (pIdx->nColumn>iCol ? pIdx->aAvgEq[iCol] : 0);
if( iLower>=iUpper ){
iGap = 0;
}else{
@@ -2466,7 +2467,7 @@ static int whereRangeScanEst(
&& OptimizationEnabled(pParse->db, SQLITE_Stat3)
){
UnpackedRecord *pRec = pBuilder->pRec;
tRowcnt a[2];
LogEst a[2];
u8 aff;
/* Variable iLower will be set to the estimate of the number of rows in
@@ -2486,8 +2487,8 @@ static int whereRangeScanEst(
** is either ($P) or ($P:$U). Again, even if $U is available, both values
** of iUpper are requested of whereKeyStats() and the smaller used.
*/
tRowcnt iLower;
tRowcnt iUpper;
LogEst iLower;
LogEst iUpper;
if( nEq==p->nColumn ){
aff = SQLITE_AFF_INTEGER;
@@ -2503,7 +2504,7 @@ static int whereRangeScanEst(
** have been requested when testing key $P in whereEqualScanEst(). */
whereKeyStats(pParse, p, pRec, 0, a);
iLower = a[0];
iUpper = a[0] + a[1];
iUpper = sqlite3LogEstAdd(a[0],a[1]);
}
/* If possible, improve on the iLower estimate using ($P:$L). */
@@ -2513,9 +2514,9 @@ static int whereRangeScanEst(
assert( (pLower->eOperator & (WO_GT|WO_GE))!=0 );
rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
if( rc==SQLITE_OK && bOk ){
tRowcnt iNew;
LogEst iNew;
whereKeyStats(pParse, p, pRec, 0, a);
iNew = a[0] + ((pLower->eOperator & WO_GT) ? a[1] : 0);
iNew = sqlite3LogEstAdd(a[0],((pLower->eOperator & WO_GT) ? a[1] : 0));
if( iNew>iLower ) iLower = iNew;
nOut--;
}
@@ -2528,9 +2529,9 @@ static int whereRangeScanEst(
assert( (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
if( rc==SQLITE_OK && bOk ){
tRowcnt iNew;
LogEst iNew;
whereKeyStats(pParse, p, pRec, 1, a);
iNew = a[0] + ((pUpper->eOperator & WO_LE) ? a[1] : 0);
iNew = sqlite3LogEstAdd(a[0],((pUpper->eOperator & WO_LE) ? a[1] : 0));
if( iNew<iUpper ) iUpper = iNew;
nOut--;
}
@@ -2538,17 +2539,17 @@ static int whereRangeScanEst(
pBuilder->pRec = pRec;
if( rc==SQLITE_OK ){
if( iUpper>iLower ){
nNew = sqlite3LogEst(iUpper - iLower);
}else{
nNew = 10; assert( 10==sqlite3LogEst(2) );
}
if( iUpper<=iLower ) iUpper = iLower+1;
nNew = sqlite3LogEst(sqlite3LogEstToInt(iUpper)
- sqlite3LogEstToInt(iLower));
if( nNew<nOut ){
nOut = nNew;
}
*pnOut = (LogEst)nOut;
WHERETRACE(0x100, ("range scan regions: %u..%u est=%d\n",
(u32)iLower, (u32)iUpper, nOut));
WHERETRACE(0x100, ("range scan regions: %llu..%llu est=%d\n",
sqlite3LogEstToInt(iLower),
sqlite3LogEstToInt(iUpper),
nOut));
return SQLITE_OK;
}
}
@@ -2596,14 +2597,14 @@ static int whereEqualScanEst(
Parse *pParse, /* Parsing & code generating context */
WhereLoopBuilder *pBuilder,
Expr *pExpr, /* Expression for VALUE in the x=VALUE constraint */
tRowcnt *pnRow /* Write the revised row estimate here */
LogEst *pnRow /* Write the revised row estimate here */
){
Index *p = pBuilder->pNew->u.btree.pIndex;
int nEq = pBuilder->pNew->u.btree.nEq;
UnpackedRecord *pRec = pBuilder->pRec;
u8 aff; /* Column affinity */
int rc; /* Subfunction return code */
tRowcnt a[2]; /* Statistics */
LogEst a[2]; /* Statistics */
int bOk;
assert( nEq>=1 );
@@ -2633,7 +2634,8 @@ static int whereEqualScanEst(
pBuilder->nRecValid = nEq;
whereKeyStats(pParse, p, pRec, 0, a);
WHERETRACE(0x100,("equality scan regions: %d\n", (int)a[1]));
WHERETRACE(0x100,("equality scan regions: %d (%llu)\n", a[1],
sqlite3LogEstToInt(a[1])));
*pnRow = a[1];
return rc;
@@ -2661,27 +2663,28 @@ static int whereInScanEst(
Parse *pParse, /* Parsing & code generating context */
WhereLoopBuilder *pBuilder,
ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */
tRowcnt *pnRow /* Write the revised row estimate here */
LogEst *pnRow /* Write the revised row estimate here */
){
Index *p = pBuilder->pNew->u.btree.pIndex;
int nRecValid = pBuilder->nRecValid;
int rc = SQLITE_OK; /* Subfunction return code */
tRowcnt nEst; /* Number of rows for a single term */
tRowcnt nRowEst = 0; /* New estimate of the number of rows */
LogEst nEst; /* Number of rows for a single term */
u64 nRowEst = 0; /* New estimate of the number of rows */
int i; /* Loop counter */
assert( p->aSample!=0 );
for(i=0; rc==SQLITE_OK && i<pList->nExpr; i++){
nEst = p->aiRowEst[0];
rc = whereEqualScanEst(pParse, pBuilder, pList->a[i].pExpr, &nEst);
nRowEst += nEst;
nRowEst += sqlite3LogEstToInt(nEst);
pBuilder->nRecValid = nRecValid;
}
if( rc==SQLITE_OK ){
if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0];
*pnRow = nRowEst;
WHERETRACE(0x100,("IN row estimate: est=%g\n", nRowEst));
nEst = sqlite3LogEst(nRowEst);
if( nEst > p->aiRowEst[0] ) nEst = p->aiRowEst[0];
*pnRow = nEst;
WHERETRACE(0x100,("IN row estimate: est=%d (%llu)\n", nEst, nRowEst));
}
assert( pBuilder->nRecValid==nRecValid );
return rc;
@@ -4251,8 +4254,8 @@ static int whereLoopAddBtreeIndex(
assert( pNew->u.btree.nEq<=pProbe->nColumn );
if( pNew->u.btree.nEq < pProbe->nColumn ){
iCol = pProbe->aiColumn[pNew->u.btree.nEq];
nRowEst = sqlite3LogEst(pProbe->aiRowEst[pNew->u.btree.nEq+1]);
if( nRowEst==0 && pProbe->onError==OE_None ) nRowEst = 1;
nRowEst = pProbe->aiRowEst[pNew->u.btree.nEq+1];
if( nRowEst<10 && pProbe->onError==OE_None ) nRowEst = 10;
}else{
iCol = -1;
nRowEst = 0;
@@ -4265,7 +4268,7 @@ static int whereLoopAddBtreeIndex(
saved_prereq = pNew->prereq;
saved_nOut = pNew->nOut;
pNew->rSetup = 0;
rLogSize = estLog(sqlite3LogEst(pProbe->aiRowEst[0]));
rLogSize = estLog(pProbe->aiRowEst[0]);
for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
int nIn = 0;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
@@ -4346,7 +4349,7 @@ static int whereLoopAddBtreeIndex(
&& OptimizationEnabled(db, SQLITE_Stat3)
){
Expr *pExpr = pTerm->pExpr;
tRowcnt nOut = 0;
LogEst nOut = pNew->nOut;
if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){
testcase( pTerm->eOperator & WO_EQ );
testcase( pTerm->eOperator & WO_ISNULL );
@@ -4355,11 +4358,8 @@ static int whereLoopAddBtreeIndex(
&& !ExprHasProperty(pExpr, EP_xIsSelect) ){
rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut);
}
assert( nOut==0 || rc==SQLITE_OK );
if( nOut ){
nOut = sqlite3LogEst(nOut);
pNew->nOut = MIN(nOut, saved_nOut);
}
assert( nOut==pNew->nOut || rc==SQLITE_OK );
if( nOut<pNew->nOut ) pNew->nOut = nOut;
}
#endif
if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){
@@ -4460,7 +4460,7 @@ static int whereLoopAddBtree(
WhereInfo *pWInfo; /* WHERE analysis context */
Index *pProbe; /* An index we are evaluating */
Index sPk; /* A fake index object for the primary key */
tRowcnt aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */
LogEst aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */
int aiColumnPk = -1; /* The aColumn[] value for the sPk index */
SrcList *pTabList; /* The FROM clause */
struct SrcList_item *pSrc; /* The FROM clause btree term to add */
@@ -4495,7 +4495,7 @@ static int whereLoopAddBtree(
sPk.onError = OE_Replace;
sPk.pTable = pSrc->pTab;
aiRowEstPk[0] = pSrc->pTab->nRowEst;
aiRowEstPk[1] = 1;
aiRowEstPk[1] = 0;
pFirst = pSrc->pTab->pIndex;
if( pSrc->notIndexed==0 ){
/* The real indices of the table are only considered if the
@@ -4504,7 +4504,7 @@ static int whereLoopAddBtree(
}
pProbe = &sPk;
}
rSize = sqlite3LogEst(pSrc->pTab->nRowEst);
rSize = pSrc->pTab->nRowEst;
rLogSize = estLog(rSize);
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX