1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-10 01:02:56 +03:00

Store values loaded from the stat1 table as logarithmic values in memory.

FossilOrigin-Name: 1bd74c49ddab6f53bb6eaa57907eff44c2580dd6
This commit is contained in:
dan
2014-04-25 15:01:01 +00:00
parent aa9933c115
commit cfc9df76e1
8 changed files with 72 additions and 51 deletions

View File

@@ -1,5 +1,5 @@
C Changes\sto\sthe\sway\sthe\splanner\scalculates\sthe\scosts\sof\svarious\stable\sand\sindex\sscans.\sSome\stest\scases\sstill\sfailing. C Store\svalues\sloaded\sfrom\sthe\sstat1\stable\sas\slogarithmic\svalues\sin\smemory.
D 2014-04-24T20:04:49.939 D 2014-04-25T15:01:01.691
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -158,7 +158,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494 F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c b00900877f766f116f9e16116f1ccacdc21d82f1 F src/alter.c b00900877f766f116f9e16116f1ccacdc21d82f1
F src/analyze.c 663e0b291d27eb03c9fd6b421e2d61ba348a2389 F src/analyze.c 92f1495304dd33b4f9e0b0e5aa030b068ada504d
F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52 F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53
@@ -167,7 +167,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c 6c9b51abd404ce5b78b173b6f2248e8cb824758c F src/btree.c 6c9b51abd404ce5b78b173b6f2248e8cb824758c
F src/btree.h d79306df4ed9181b48916737fe8871a4392c4594 F src/btree.h d79306df4ed9181b48916737fe8871a4392c4594
F src/btreeInt.h cf180d86b2e9e418f638d65baa425c4c69c0e0e3 F src/btreeInt.h cf180d86b2e9e418f638d65baa425c4c69c0e0e3
F src/build.c 5bfeea8f302ec2926c9eea321a61daea92a29fa4 F src/build.c 9f7b2ed2af66dd2d186c0835d1c2a672d1f768e0
F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c 0231df905e2c4abba4483ee18ffc05adc321df2a F src/ctime.c 0231df905e2c4abba4483ee18ffc05adc321df2a
@@ -211,18 +211,18 @@ F src/parse.y 22d6a074e5f5a7258947a1dc55a9bf946b765dd0
F src/pcache.c d8eafac28290d4bb80332005435db44991d07fc2 F src/pcache.c d8eafac28290d4bb80332005435db44991d07fc2
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
F src/pcache1.c 102e6f5a2fbc646154463eb856d1fd716867b64c F src/pcache1.c 102e6f5a2fbc646154463eb856d1fd716867b64c
F src/pragma.c 21ece94d4f3e76e8e150deecafb9c7abd398ec67 F src/pragma.c 810ef31ccfaa233201dcf100637a9777cc24e897
F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337 F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337
F src/printf.c e5a0005f8b3de21f85da6a709d2fbee76775bf4b F src/printf.c e5a0005f8b3de21f85da6a709d2fbee76775bf4b
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66 F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66
F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be
F src/select.c bc7feff0fb4c4a1b9d655b717bef166846b48e33 F src/select.c ed459f7f478a1e533d19c4b953693b3ffa2efd15
F src/shell.c 2afe7a7154e97be0c74c5feacf09626bda8493be F src/shell.c 2afe7a7154e97be0c74c5feacf09626bda8493be
F src/sqlite.h.in bde98816e1ba0c9ffef50afe7b32f4e5a8f54fe0 F src/sqlite.h.in bde98816e1ba0c9ffef50afe7b32f4e5a8f54fe0
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
F src/sqliteInt.h 03e2f60ccb0745fa2d3a072cb4f75fa29251d2ee F src/sqliteInt.h bad694fd6b91b10a7a5aafa16fd05b504bad6b6e
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -291,7 +291,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8 F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45
F src/where.c c12bc20cd649bcae39de3e452bfc1a3f164454ee F src/where.c 15a5c94c8c93500e141c6cb25af600615dc196d8
F src/whereInt.h 929c1349b5355fd44f22cee5c14d72b3329c58a6 F src/whereInt.h 929c1349b5355fd44f22cee5c14d72b3329c58a6
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@@ -1161,10 +1161,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
P 65d2544af9adc1e2f1d193e57f8be0422fb0d5eb P c5a6ec0a880652dc8f4593d9f7acd58ddc3dc5f3
R 6cc54703275bf2ed6708c34ae52cf7ea R 63fad85eb66cf540e6aa11923b167cbf
T *branch * experimental-costs
T *sym-experimental-costs *
T -sym-trunk *
U dan U dan
Z 868aa60f36dda291ae018583501645e5 Z 04f4e3645ebd9e33526df3bd26c04a76

View File

@@ -1 +1 @@
c5a6ec0a880652dc8f4593d9f7acd58ddc3dc5f3 1bd74c49ddab6f53bb6eaa57907eff44c2580dd6

View File

@@ -1371,6 +1371,7 @@ static void decodeIntArray(
char *zIntArray, /* String containing int array to decode */ char *zIntArray, /* String containing int array to decode */
int nOut, /* Number of slots in aOut[] */ int nOut, /* Number of slots in aOut[] */
tRowcnt *aOut, /* Store integers here */ tRowcnt *aOut, /* Store integers here */
LogEst *aLog, /* Or, if aOut==0, here */
Index *pIndex /* Handle extra flags for this index, if not NULL */ Index *pIndex /* Handle extra flags for this index, if not NULL */
){ ){
char *z = zIntArray; char *z = zIntArray;
@@ -1389,7 +1390,11 @@ static void decodeIntArray(
v = v*10 + c - '0'; v = v*10 + c - '0';
z++; z++;
} }
aOut[i] = v; if( aOut ){
aOut[i] = v;
}else{
aLog[i] = sqlite3LogEst(v);
}
if( *z==' ' ) z++; if( *z==' ' ) z++;
} }
#ifndef SQLITE_ENABLE_STAT3_OR_STAT4 #ifndef SQLITE_ENABLE_STAT3_OR_STAT4
@@ -1445,12 +1450,12 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
z = argv[2]; z = argv[2];
if( pIndex ){ if( pIndex ){
decodeIntArray((char*)z, pIndex->nKeyCol+1, pIndex->aiRowEst, pIndex); decodeIntArray((char*)z, pIndex->nKeyCol+1, 0, pIndex->aiRowLogEst, pIndex);
if( pIndex->pPartIdxWhere==0 ) pTable->nRowEst = pIndex->aiRowEst[0]; if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
}else{ }else{
Index fakeIdx; Index fakeIdx;
fakeIdx.szIdxRow = pTable->szTabRow; fakeIdx.szIdxRow = pTable->szTabRow;
decodeIntArray((char*)z, 1, &pTable->nRowEst, &fakeIdx); decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx);
pTable->szTabRow = fakeIdx.szIdxRow; pTable->szTabRow = fakeIdx.szIdxRow;
} }
@@ -1642,9 +1647,9 @@ static int loadStatTbl(
pPrevIdx = pIdx; pPrevIdx = pIdx;
} }
pSample = &pIdx->aSample[pIdx->nSample]; pSample = &pIdx->aSample[pIdx->nSample];
decodeIntArray((char*)sqlite3_column_text(pStmt,1), nCol, pSample->anEq, 0); decodeIntArray((char*)sqlite3_column_text(pStmt,1),nCol,pSample->anEq,0,0);
decodeIntArray((char*)sqlite3_column_text(pStmt,2), nCol, pSample->anLt, 0); decodeIntArray((char*)sqlite3_column_text(pStmt,2),nCol,pSample->anLt,0,0);
decodeIntArray((char*)sqlite3_column_text(pStmt,3), nCol, pSample->anDLt,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. /* 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 ** This is in case the sample record is corrupted. In that case, the

View File

@@ -905,7 +905,7 @@ void sqlite3StartTable(
pTable->iPKey = -1; pTable->iPKey = -1;
pTable->pSchema = db->aDb[iDb].pSchema; pTable->pSchema = db->aDb[iDb].pSchema;
pTable->nRef = 1; pTable->nRef = 1;
pTable->nRowEst = 1048576; pTable->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
assert( pParse->pNewTable==0 ); assert( pParse->pNewTable==0 );
pParse->pNewTable = pTable; pParse->pNewTable = pTable;
@@ -2730,15 +2730,15 @@ Index *sqlite3AllocateIndexObject(
nByte = ROUND8(sizeof(Index)) + /* Index structure */ nByte = ROUND8(sizeof(Index)) + /* Index structure */
ROUND8(sizeof(char*)*nCol) + /* Index.azColl */ 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(i16)*nCol + /* Index.aiColumn */
sizeof(u8)*nCol); /* Index.aSortOrder */ sizeof(u8)*nCol); /* Index.aSortOrder */
p = sqlite3DbMallocZero(db, nByte + nExtra); p = sqlite3DbMallocZero(db, nByte + nExtra);
if( p ){ if( p ){
char *pExtra = ((char*)p)+ROUND8(sizeof(Index)); char *pExtra = ((char*)p)+ROUND8(sizeof(Index));
p->azColl = (char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol); p->azColl = (char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol);
p->aiRowEst = (tRowcnt*)pExtra; pExtra += sizeof(tRowcnt)*(nCol+1); p->aiRowLogEst = (LogEst*)pExtra; pExtra += sizeof(LogEst)*(nCol+1);
p->aiColumn = (i16*)pExtra; pExtra += sizeof(i16)*nCol; p->aiColumn = (i16*)pExtra; pExtra += sizeof(i16)*nCol;
p->aSortOrder = (u8*)pExtra; p->aSortOrder = (u8*)pExtra;
p->nColumn = nCol; p->nColumn = nCol;
p->nKeyCol = nCol - 1; p->nKeyCol = nCol - 1;
@@ -2968,7 +2968,7 @@ Index *sqlite3CreateIndex(
if( db->mallocFailed ){ if( db->mallocFailed ){
goto exit_create_index; goto exit_create_index;
} }
assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowEst) ); assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowLogEst) );
assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) ); assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) );
pIndex->zName = zExtra; pIndex->zName = zExtra;
zExtra += nName + 1; zExtra += nName + 1;
@@ -3249,7 +3249,7 @@ exit_create_index:
** Since we do not know, guess 1 million. aiRowEst[1] is an estimate of the ** 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 ** 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 ** 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 ** of the index. And so forth. It must always be the case that
* *
** aiRowEst[N]<=aiRowEst[N-1] ** aiRowEst[N]<=aiRowEst[N-1]
@@ -3260,6 +3260,7 @@ exit_create_index:
** are based on typical values found in actual indices. ** are based on typical values found in actual indices.
*/ */
void sqlite3DefaultRowEst(Index *pIdx){ void sqlite3DefaultRowEst(Index *pIdx){
#if 0
tRowcnt *a = pIdx->aiRowEst; tRowcnt *a = pIdx->aiRowEst;
int i; int i;
tRowcnt n; tRowcnt n;
@@ -3274,6 +3275,17 @@ void sqlite3DefaultRowEst(Index *pIdx){
if( pIdx->onError!=OE_None ){ if( pIdx->onError!=OE_None ){
a[pIdx->nKeyCol] = 1; 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;
}
} }
/* /*

View File

@@ -1488,13 +1488,15 @@ void sqlite3Pragma(
sqlite3VdbeAddOp2(v, OP_Null, 0, 2); sqlite3VdbeAddOp2(v, OP_Null, 0, 2);
sqlite3VdbeAddOp2(v, OP_Integer, sqlite3VdbeAddOp2(v, OP_Integer,
(int)sqlite3LogEstToInt(pTab->szTabRow), 3); (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); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0); sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0);
sqlite3VdbeAddOp2(v, OP_Integer, sqlite3VdbeAddOp2(v, OP_Integer,
(int)sqlite3LogEstToInt(pIdx->szIdxRow), 3); (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); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
} }
} }

View File

@@ -1690,7 +1690,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
assert( db->lookaside.bEnabled==0 ); assert( db->lookaside.bEnabled==0 );
pTab->nRef = 1; pTab->nRef = 1;
pTab->zName = 0; pTab->zName = 0;
pTab->nRowEst = 1048576; pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
selectAddColumnTypeAndCollation(pParse, pTab, pSelect); selectAddColumnTypeAndCollation(pParse, pTab, pSelect);
pTab->iPKey = -1; pTab->iPKey = -1;
@@ -3829,7 +3829,7 @@ static int withExpand(
pTab->nRef = 1; pTab->nRef = 1;
pTab->zName = sqlite3DbStrDup(db, pCte->zName); pTab->zName = sqlite3DbStrDup(db, pCte->zName);
pTab->iPKey = -1; pTab->iPKey = -1;
pTab->nRowEst = 1048576; pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
pTab->tabFlags |= TF_Ephemeral; pTab->tabFlags |= TF_Ephemeral;
pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0); pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
if( db->mallocFailed ) return SQLITE_NOMEM; if( db->mallocFailed ) return SQLITE_NOMEM;
@@ -4005,7 +4005,7 @@ static int selectExpander(Walker *pWalker, Select *p){
while( pSel->pPrior ){ pSel = pSel->pPrior; } while( pSel->pPrior ){ pSel = pSel->pPrior; }
selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol); selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol);
pTab->iPKey = -1; pTab->iPKey = -1;
pTab->nRowEst = 1048576; pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
pTab->tabFlags |= TF_Ephemeral; pTab->tabFlags |= TF_Ephemeral;
#endif #endif
}else{ }else{
@@ -4655,7 +4655,7 @@ int sqlite3Select(
sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn); sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
sqlite3Select(pParse, pSub, &dest); sqlite3Select(pParse, pSub, &dest);
pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow; pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow);
pItem->viaCoroutine = 1; pItem->viaCoroutine = 1;
pItem->regResult = dest.iSdst; pItem->regResult = dest.iSdst;
sqlite3VdbeAddOp1(v, OP_EndCoroutine, pItem->regReturn); sqlite3VdbeAddOp1(v, OP_EndCoroutine, pItem->regReturn);
@@ -4686,7 +4686,7 @@ int sqlite3Select(
sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
sqlite3Select(pParse, pSub, &dest); sqlite3Select(pParse, pSub, &dest);
pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow; pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow);
if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn); retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
VdbeComment((v, "end %s", pItem->pTab->zName)); VdbeComment((v, "end %s", pItem->pTab->zName));

View File

@@ -1471,7 +1471,7 @@ struct Table {
#ifndef SQLITE_OMIT_CHECK #ifndef SQLITE_OMIT_CHECK
ExprList *pCheck; /* All CHECK constraints */ ExprList *pCheck; /* All CHECK constraints */
#endif #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) */ int tnum; /* Root BTree node for this table (see note above) */
i16 iPKey; /* If not negative, use aCol[iPKey] as the primary key */ i16 iPKey; /* If not negative, use aCol[iPKey] as the primary key */
i16 nCol; /* Number of columns in this table */ i16 nCol; /* Number of columns in this table */
@@ -1680,7 +1680,10 @@ struct UnpackedRecord {
struct Index { struct Index {
char *zName; /* Name of this index */ char *zName; /* Name of this index */
i16 *aiColumn; /* Which columns are used by this index. 1st is 0 */ i16 *aiColumn; /* Which columns are used by this index. 1st is 0 */
#if 0
tRowcnt *aiRowEst; /* From ANALYZE: Est. rows selected by each column */ 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 */ Table *pTable; /* The SQL table being indexed */
char *zColAff; /* String defining the affinity of each column */ char *zColAff; /* String defining the affinity of each column */
Index *pNext; /* The next index associated with the same table */ Index *pNext; /* The next index associated with the same table */

View File

@@ -1956,7 +1956,8 @@ static void whereKeyStats(
iLower = 0; iLower = 0;
iUpper = aSample[0].anLt[iCol]; iUpper = aSample[0].anLt[iCol];
}else{ }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]; iLower = aSample[i-1].anEq[iCol] + aSample[i-1].anLt[iCol];
} }
aStat[1] = (pIdx->nKeyCol>iCol ? pIdx->aAvgEq[iCol] : 1); aStat[1] = (pIdx->nKeyCol>iCol ? pIdx->aAvgEq[iCol] : 1);
@@ -2092,7 +2093,7 @@ static int whereRangeScanEst(
/* Determine iLower and iUpper using ($P) only. */ /* Determine iLower and iUpper using ($P) only. */
if( nEq==0 ){ if( nEq==0 ){
iLower = 0; iLower = 0;
iUpper = p->aiRowEst[0]; iUpper = sqlite3LogEstToInt(p->aiRowLogEst[0]);
}else{ }else{
/* Note: this call could be optimized away - since the same values must /* Note: this call could be optimized away - since the same values must
** have been requested when testing key $P in whereEqualScanEst(). */ ** have been requested when testing key $P in whereEqualScanEst(). */
@@ -2251,6 +2252,7 @@ static int whereInScanEst(
tRowcnt *pnRow /* Write the revised row estimate here */ tRowcnt *pnRow /* Write the revised row estimate here */
){ ){
Index *p = pBuilder->pNew->u.btree.pIndex; Index *p = pBuilder->pNew->u.btree.pIndex;
i64 nRow0 = sqlite3LogEstToInt(p->aiRowLogEst[0]);
int nRecValid = pBuilder->nRecValid; int nRecValid = pBuilder->nRecValid;
int rc = SQLITE_OK; /* Subfunction return code */ int rc = SQLITE_OK; /* Subfunction return code */
tRowcnt nEst; /* Number of rows for a single term */ tRowcnt nEst; /* Number of rows for a single term */
@@ -2259,14 +2261,14 @@ static int whereInScanEst(
assert( p->aSample!=0 ); assert( p->aSample!=0 );
for(i=0; rc==SQLITE_OK && i<pList->nExpr; i++){ 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); rc = whereEqualScanEst(pParse, pBuilder, pList->a[i].pExpr, &nEst);
nRowEst += nEst; nRowEst += nEst;
pBuilder->nRecValid = nRecValid; pBuilder->nRecValid = nRecValid;
} }
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0]; if( nRowEst > nRow0 ) nRowEst = nRow0;
*pnRow = nRowEst; *pnRow = nRowEst;
WHERETRACE(0x10,("IN row estimate: est=%g\n", nRowEst)); WHERETRACE(0x10,("IN row estimate: est=%g\n", nRowEst));
} }
@@ -4059,8 +4061,7 @@ static int whereLoopAddBtreeIndex(
assert( pNew->u.btree.nEq<=pProbe->nKeyCol ); assert( pNew->u.btree.nEq<=pProbe->nKeyCol );
if( pNew->u.btree.nEq < pProbe->nKeyCol ){ if( pNew->u.btree.nEq < pProbe->nKeyCol ){
iCol = pProbe->aiColumn[pNew->u.btree.nEq]; iCol = pProbe->aiColumn[pNew->u.btree.nEq];
nRowEst = sqlite3LogEst(pProbe->aiRowEst[pNew->u.btree.nEq+1]); nRowEst = pProbe->aiRowLogEst[pNew->u.btree.nEq+1];
if( nRowEst==0 && pProbe->onError==OE_None ) nRowEst = 1;
}else{ }else{
iCol = -1; iCol = -1;
nRowEst = 0; nRowEst = 0;
@@ -4074,7 +4075,7 @@ static int whereLoopAddBtreeIndex(
saved_prereq = pNew->prereq; saved_prereq = pNew->prereq;
saved_nOut = pNew->nOut; saved_nOut = pNew->nOut;
pNew->rSetup = 0; 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 /* 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 ** available for the left-most terms of the index, and if the average
@@ -4082,10 +4083,11 @@ static int whereLoopAddBtreeIndex(
** number 18 was found by experimentation to be the payoff point where ** number 18 was found by experimentation to be the payoff point where
** skip-scan become faster than a full-scan. ** skip-scan become faster than a full-scan.
*/ */
assert( 42==sqlite3LogEst(18) );
if( pTerm==0 if( pTerm==0
&& saved_nEq==saved_nSkip && saved_nEq==saved_nSkip
&& saved_nEq+1<pProbe->nKeyCol && 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 && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK
){ ){
LogEst nIter; LogEst nIter;
@@ -4093,7 +4095,7 @@ static int whereLoopAddBtreeIndex(
pNew->u.btree.nSkip++; pNew->u.btree.nSkip++;
pNew->aLTerm[pNew->nLTerm++] = 0; pNew->aLTerm[pNew->nLTerm++] = 0;
pNew->wsFlags |= WHERE_SKIPSCAN; 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->rRun = rLogSize + nIter;
pNew->nOut += nIter; pNew->nOut += nIter;
whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter); whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter);
@@ -4305,7 +4307,7 @@ static int whereLoopAddBtree(
WhereInfo *pWInfo; /* WHERE analysis context */ WhereInfo *pWInfo; /* WHERE analysis context */
Index *pProbe; /* An index we are evaluating */ Index *pProbe; /* An index we are evaluating */
Index sPk; /* A fake index object for the primary key */ 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 */ i16 aiColumnPk = -1; /* The aColumn[] value for the sPk index */
SrcList *pTabList; /* The FROM clause */ SrcList *pTabList; /* The FROM clause */
struct SrcList_item *pSrc; /* The FROM clause btree term to add */ struct SrcList_item *pSrc; /* The FROM clause btree term to add */
@@ -4340,12 +4342,12 @@ static int whereLoopAddBtree(
memset(&sPk, 0, sizeof(Index)); memset(&sPk, 0, sizeof(Index));
sPk.nKeyCol = 1; sPk.nKeyCol = 1;
sPk.aiColumn = &aiColumnPk; sPk.aiColumn = &aiColumnPk;
sPk.aiRowEst = aiRowEstPk; sPk.aiRowLogEst = aiRowEstPk;
sPk.onError = OE_Replace; sPk.onError = OE_Replace;
sPk.pTable = pTab; sPk.pTable = pTab;
sPk.szIdxRow = pTab->szTabRow; sPk.szIdxRow = pTab->szTabRow;
aiRowEstPk[0] = pTab->nRowEst; aiRowEstPk[0] = pTab->nRowLogEst;
aiRowEstPk[1] = 1; aiRowEstPk[1] = 0;
pFirst = pSrc->pTab->pIndex; pFirst = pSrc->pTab->pIndex;
if( pSrc->notIndexed==0 ){ if( pSrc->notIndexed==0 ){
/* The real indices of the table are only considered if the /* The real indices of the table are only considered if the
@@ -4354,7 +4356,7 @@ static int whereLoopAddBtree(
} }
pProbe = &sPk; pProbe = &sPk;
} }
rSize = sqlite3LogEst(pTab->nRowEst); rSize = pTab->nRowLogEst;
rLogSize = estLog(rSize); rLogSize = estLog(rSize);
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX #ifndef SQLITE_OMIT_AUTOMATIC_INDEX