-C Changes\sto\sthe\sway\sthe\splanner\scalculates\sthe\scosts\sof\svarious\stable\sand\sindex\sscans.\sSome\stest\scases\sstill\sfailing.
-D 2014-04-24T20:04:49.939
+C Store\svalues\sloaded\sfrom\sthe\sstat1\stable\sas\slogarithmic\svalues\sin\smemory.
+D 2014-04-25T15:01:01.691
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c b00900877f766f116f9e16116f1ccacdc21d82f1
-F src/analyze.c 663e0b291d27eb03c9fd6b421e2d61ba348a2389
+F src/analyze.c 92f1495304dd33b4f9e0b0e5aa030b068ada504d
F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53
F src/btree.c 6c9b51abd404ce5b78b173b6f2248e8cb824758c
F src/btree.h d79306df4ed9181b48916737fe8871a4392c4594
F src/btreeInt.h cf180d86b2e9e418f638d65baa425c4c69c0e0e3
-F src/build.c 5bfeea8f302ec2926c9eea321a61daea92a29fa4
+F src/build.c 9f7b2ed2af66dd2d186c0835d1c2a672d1f768e0
F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c 0231df905e2c4abba4483ee18ffc05adc321df2a
F src/pcache.c d8eafac28290d4bb80332005435db44991d07fc2
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
F src/pcache1.c 102e6f5a2fbc646154463eb856d1fd716867b64c
-F src/pragma.c 21ece94d4f3e76e8e150deecafb9c7abd398ec67
+F src/pragma.c 810ef31ccfaa233201dcf100637a9777cc24e897
F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337
F src/printf.c e5a0005f8b3de21f85da6a709d2fbee76775bf4b
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66
F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be
-F src/select.c bc7feff0fb4c4a1b9d655b717bef166846b48e33
+F src/select.c ed459f7f478a1e533d19c4b953693b3ffa2efd15
F src/shell.c 2afe7a7154e97be0c74c5feacf09626bda8493be
F src/sqlite.h.in bde98816e1ba0c9ffef50afe7b32f4e5a8f54fe0
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
-F src/sqliteInt.h 03e2f60ccb0745fa2d3a072cb4f75fa29251d2ee
+F src/sqliteInt.h bad694fd6b91b10a7a5aafa16fd05b504bad6b6e
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45
-F src/where.c c12bc20cd649bcae39de3e452bfc1a3f164454ee
+F src/where.c 15a5c94c8c93500e141c6cb25af600615dc196d8
F src/whereInt.h 929c1349b5355fd44f22cee5c14d72b3329c58a6
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 65d2544af9adc1e2f1d193e57f8be0422fb0d5eb
-R 6cc54703275bf2ed6708c34ae52cf7ea
-T *branch * experimental-costs
-T *sym-experimental-costs *
-T -sym-trunk *
+P c5a6ec0a880652dc8f4593d9f7acd58ddc3dc5f3
+R 63fad85eb66cf540e6aa11923b167cbf
U dan
-Z 868aa60f36dda291ae018583501645e5
+Z 04f4e3645ebd9e33526df3bd26c04a76
-c5a6ec0a880652dc8f4593d9f7acd58ddc3dc5f3
\ No newline at end of file
+1bd74c49ddab6f53bb6eaa57907eff44c2580dd6
\ No newline at end of file
char *zIntArray, /* String containing int array to decode */
int nOut, /* Number of slots in aOut[] */
tRowcnt *aOut, /* Store integers here */
+ LogEst *aLog, /* Or, if aOut==0, here */
Index *pIndex /* Handle extra flags for this index, if not NULL */
){
char *z = zIntArray;
v = v*10 + c - '0';
z++;
}
- aOut[i] = v;
+ if( aOut ){
+ aOut[i] = v;
+ }else{
+ aLog[i] = sqlite3LogEst(v);
+ }
if( *z==' ' ) z++;
}
#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
z = argv[2];
if( pIndex ){
- decodeIntArray((char*)z, pIndex->nKeyCol+1, pIndex->aiRowEst, pIndex);
- if( pIndex->pPartIdxWhere==0 ) pTable->nRowEst = pIndex->aiRowEst[0];
+ decodeIntArray((char*)z, pIndex->nKeyCol+1, 0, pIndex->aiRowLogEst, pIndex);
+ if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
}else{
Index fakeIdx;
fakeIdx.szIdxRow = pTable->szTabRow;
- decodeIntArray((char*)z, 1, &pTable->nRowEst, &fakeIdx);
+ decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx);
pTable->szTabRow = fakeIdx.szIdxRow;
}
pPrevIdx = pIdx;
}
pSample = &pIdx->aSample[pIdx->nSample];
- decodeIntArray((char*)sqlite3_column_text(pStmt,1), nCol, pSample->anEq, 0);
- decodeIntArray((char*)sqlite3_column_text(pStmt,2), nCol, pSample->anLt, 0);
- decodeIntArray((char*)sqlite3_column_text(pStmt,3), nCol, pSample->anDLt,0);
+ decodeIntArray((char*)sqlite3_column_text(pStmt,1),nCol,pSample->anEq,0,0);
+ decodeIntArray((char*)sqlite3_column_text(pStmt,2),nCol,pSample->anLt,0,0);
+ decodeIntArray((char*)sqlite3_column_text(pStmt,3),nCol,pSample->anDLt,0,0);
/* Take a copy of the sample. Add two 0x00 bytes the end of the buffer.
** This is in case the sample record is corrupted. In that case, the
pTable->iPKey = -1;
pTable->pSchema = db->aDb[iDb].pSchema;
pTable->nRef = 1;
- pTable->nRowEst = 1048576;
+ pTable->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
assert( pParse->pNewTable==0 );
pParse->pNewTable = pTable;
nByte = ROUND8(sizeof(Index)) + /* Index structure */
ROUND8(sizeof(char*)*nCol) + /* Index.azColl */
- ROUND8(sizeof(tRowcnt)*(nCol+1) + /* Index.aiRowEst */
+ ROUND8(sizeof(LogEst)*(nCol+1) + /* Index.aiRowLogEst */
sizeof(i16)*nCol + /* Index.aiColumn */
sizeof(u8)*nCol); /* Index.aSortOrder */
p = sqlite3DbMallocZero(db, nByte + nExtra);
if( p ){
char *pExtra = ((char*)p)+ROUND8(sizeof(Index));
- p->azColl = (char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol);
- p->aiRowEst = (tRowcnt*)pExtra; pExtra += sizeof(tRowcnt)*(nCol+1);
- p->aiColumn = (i16*)pExtra; pExtra += sizeof(i16)*nCol;
+ p->azColl = (char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol);
+ p->aiRowLogEst = (LogEst*)pExtra; pExtra += sizeof(LogEst)*(nCol+1);
+ p->aiColumn = (i16*)pExtra; pExtra += sizeof(i16)*nCol;
p->aSortOrder = (u8*)pExtra;
p->nColumn = nCol;
p->nKeyCol = nCol - 1;
if( db->mallocFailed ){
goto exit_create_index;
}
- assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowEst) );
+ assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowLogEst) );
assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) );
pIndex->zName = zExtra;
zExtra += nName + 1;
** Since we do not know, guess 1 million. aiRowEst[1] is an estimate of the
** number of rows in the table that match any particular value of the
** first column of the index. aiRowEst[2] is an estimate of the number
-** of rows that match any particular combiniation of the first 2 columns
+** of rows that match any particular combination of the first 2 columns
** of the index. And so forth. It must always be the case that
*
** aiRowEst[N]<=aiRowEst[N-1]
** are based on typical values found in actual indices.
*/
void sqlite3DefaultRowEst(Index *pIdx){
+#if 0
tRowcnt *a = pIdx->aiRowEst;
int i;
tRowcnt n;
if( pIdx->onError!=OE_None ){
a[pIdx->nKeyCol] = 1;
}
+#endif
+ /* 1000000, 10, 9, 8, 7, 6, 5, 4, 3, 2 */
+ LogEst aVal[] = { 33, 32, 30, 28, 26, 23, 20, 16, 10 };
+ LogEst *a = pIdx->aiRowLogEst;
+ int nCopy = MIN(ArraySize(aVal), pIdx->nKeyCol);
+
+ a[0] = pIdx->pTable->nRowLogEst;
+ memcpy(&a[1], aVal, nCopy*sizeof(LogEst));
+ if( pIdx->onError!=OE_None ){
+ a[pIdx->nKeyCol] = 0;
+ }
}
/*
sqlite3VdbeAddOp2(v, OP_Null, 0, 2);
sqlite3VdbeAddOp2(v, OP_Integer,
(int)sqlite3LogEstToInt(pTab->szTabRow), 3);
- sqlite3VdbeAddOp2(v, OP_Integer, (int)pTab->nRowEst, 4);
+ sqlite3VdbeAddOp2(v, OP_Integer,
+ (int)sqlite3LogEstToInt(pTab->nRowLogEst), 4);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0);
sqlite3VdbeAddOp2(v, OP_Integer,
(int)sqlite3LogEstToInt(pIdx->szIdxRow), 3);
- sqlite3VdbeAddOp2(v, OP_Integer, (int)pIdx->aiRowEst[0], 4);
+ sqlite3VdbeAddOp2(v, OP_Integer,
+ (int)sqlite3LogEstToInt(pIdx->aiRowLogEst[0]), 4);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
}
}
assert( db->lookaside.bEnabled==0 );
pTab->nRef = 1;
pTab->zName = 0;
- pTab->nRowEst = 1048576;
+ pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
selectAddColumnTypeAndCollation(pParse, pTab, pSelect);
pTab->iPKey = -1;
pTab->nRef = 1;
pTab->zName = sqlite3DbStrDup(db, pCte->zName);
pTab->iPKey = -1;
- pTab->nRowEst = 1048576;
+ pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
pTab->tabFlags |= TF_Ephemeral;
pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
if( db->mallocFailed ) return SQLITE_NOMEM;
while( pSel->pPrior ){ pSel = pSel->pPrior; }
selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol);
pTab->iPKey = -1;
- pTab->nRowEst = 1048576;
+ pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
pTab->tabFlags |= TF_Ephemeral;
#endif
}else{
sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
sqlite3Select(pParse, pSub, &dest);
- pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow;
+ pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow);
pItem->viaCoroutine = 1;
pItem->regResult = dest.iSdst;
sqlite3VdbeAddOp1(v, OP_EndCoroutine, pItem->regReturn);
sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
sqlite3Select(pParse, pSub, &dest);
- pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow;
+ pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow);
if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
VdbeComment((v, "end %s", pItem->pTab->zName));
#ifndef SQLITE_OMIT_CHECK
ExprList *pCheck; /* All CHECK constraints */
#endif
- tRowcnt nRowEst; /* Estimated rows in table - from sqlite_stat1 table */
+ LogEst nRowLogEst; /* 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 */
struct Index {
char *zName; /* Name of this index */
i16 *aiColumn; /* Which columns are used by this index. 1st is 0 */
+#if 0
tRowcnt *aiRowEst; /* From ANALYZE: Est. rows selected by each column */
+#endif
+ LogEst *aiRowLogEst; /* 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 */
iLower = 0;
iUpper = aSample[0].anLt[iCol];
}else{
- iUpper = i>=pIdx->nSample ? pIdx->aiRowEst[0] : aSample[i].anLt[iCol];
+ i64 nRow0 = sqlite3LogEstToInt(pIdx->aiRowLogEst[0]);
+ iUpper = i>=pIdx->nSample ? nRow0 : aSample[i].anLt[iCol];
iLower = aSample[i-1].anEq[iCol] + aSample[i-1].anLt[iCol];
}
aStat[1] = (pIdx->nKeyCol>iCol ? pIdx->aAvgEq[iCol] : 1);
/* Determine iLower and iUpper using ($P) only. */
if( nEq==0 ){
iLower = 0;
- iUpper = p->aiRowEst[0];
+ iUpper = sqlite3LogEstToInt(p->aiRowLogEst[0]);
}else{
/* Note: this call could be optimized away - since the same values must
** have been requested when testing key $P in whereEqualScanEst(). */
tRowcnt *pnRow /* Write the revised row estimate here */
){
Index *p = pBuilder->pNew->u.btree.pIndex;
+ i64 nRow0 = sqlite3LogEstToInt(p->aiRowLogEst[0]);
int nRecValid = pBuilder->nRecValid;
int rc = SQLITE_OK; /* Subfunction return code */
tRowcnt nEst; /* Number of rows for a single term */
assert( p->aSample!=0 );
for(i=0; rc==SQLITE_OK && i<pList->nExpr; i++){
- nEst = p->aiRowEst[0];
+ nEst = nRow0;
rc = whereEqualScanEst(pParse, pBuilder, pList->a[i].pExpr, &nEst);
nRowEst += nEst;
pBuilder->nRecValid = nRecValid;
}
if( rc==SQLITE_OK ){
- if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0];
+ if( nRowEst > nRow0 ) nRowEst = nRow0;
*pnRow = nRowEst;
WHERETRACE(0x10,("IN row estimate: est=%g\n", nRowEst));
}
assert( pNew->u.btree.nEq<=pProbe->nKeyCol );
if( pNew->u.btree.nEq < pProbe->nKeyCol ){
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->aiRowLogEst[pNew->u.btree.nEq+1];
}else{
iCol = -1;
nRowEst = 0;
saved_prereq = pNew->prereq;
saved_nOut = pNew->nOut;
pNew->rSetup = 0;
- rLogSize = estLog(sqlite3LogEst(pProbe->aiRowEst[0]));
+ rLogSize = estLog(pProbe->aiRowLogEst[0]);
/* Consider using a skip-scan if there are no WHERE clause constraints
** available for the left-most terms of the index, and if the average
** number 18 was found by experimentation to be the payoff point where
** skip-scan become faster than a full-scan.
*/
+ assert( 42==sqlite3LogEst(18) );
if( pTerm==0
&& saved_nEq==saved_nSkip
&& saved_nEq+1<pProbe->nKeyCol
- && pProbe->aiRowEst[saved_nEq+1]>=18 /* TUNING: Minimum for skip-scan */
+ && pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */
&& (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK
){
LogEst nIter;
pNew->u.btree.nSkip++;
pNew->aLTerm[pNew->nLTerm++] = 0;
pNew->wsFlags |= WHERE_SKIPSCAN;
- nIter = sqlite3LogEst(pProbe->aiRowEst[0]/pProbe->aiRowEst[saved_nEq+1]);
+ nIter = pProbe->aiRowLogEst[0] - pProbe->aiRowLogEst[saved_nEq+1];
pNew->rRun = rLogSize + nIter;
pNew->nOut += nIter;
whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter);
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 aiRowLogEst[] value for the sPk index */
i16 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 */
memset(&sPk, 0, sizeof(Index));
sPk.nKeyCol = 1;
sPk.aiColumn = &aiColumnPk;
- sPk.aiRowEst = aiRowEstPk;
+ sPk.aiRowLogEst = aiRowEstPk;
sPk.onError = OE_Replace;
sPk.pTable = pTab;
sPk.szIdxRow = pTab->szTabRow;
- aiRowEstPk[0] = pTab->nRowEst;
- aiRowEstPk[1] = 1;
+ aiRowEstPk[0] = pTab->nRowLogEst;
+ aiRowEstPk[1] = 0;
pFirst = pSrc->pTab->pIndex;
if( pSrc->notIndexed==0 ){
/* The real indices of the table are only considered if the
}
pProbe = &sPk;
}
- rSize = sqlite3LogEst(pTab->nRowEst);
+ rSize = pTab->nRowLogEst;
rLogSize = estLog(rSize);
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX