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:
25
manifest
25
manifest
@@ -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.
|
||||
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
|
||||
@@ -158,7 +158,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
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
|
||||
@@ -167,7 +167,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
|
||||
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
|
||||
@@ -211,18 +211,18 @@ F src/parse.y 22d6a074e5f5a7258947a1dc55a9bf946b765dd0
|
||||
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
|
||||
@@ -291,7 +291,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
|
||||
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
|
||||
@@ -1161,10 +1161,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
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
|
||||
|
@@ -1 +1 @@
|
||||
c5a6ec0a880652dc8f4593d9f7acd58ddc3dc5f3
|
||||
1bd74c49ddab6f53bb6eaa57907eff44c2580dd6
|
@@ -1371,6 +1371,7 @@ static void decodeIntArray(
|
||||
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;
|
||||
@@ -1389,7 +1390,11 @@ static void decodeIntArray(
|
||||
v = v*10 + c - '0';
|
||||
z++;
|
||||
}
|
||||
if( aOut ){
|
||||
aOut[i] = v;
|
||||
}else{
|
||||
aLog[i] = sqlite3LogEst(v);
|
||||
}
|
||||
if( *z==' ' ) z++;
|
||||
}
|
||||
#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
@@ -1445,12 +1450,12 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1642,9 +1647,9 @@ static int loadStatTbl(
|
||||
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
|
||||
|
22
src/build.c
22
src/build.c
@@ -905,7 +905,7 @@ void sqlite3StartTable(
|
||||
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;
|
||||
|
||||
@@ -2730,14 +2730,14 @@ Index *sqlite3AllocateIndexObject(
|
||||
|
||||
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->aiRowLogEst = (LogEst*)pExtra; pExtra += sizeof(LogEst)*(nCol+1);
|
||||
p->aiColumn = (i16*)pExtra; pExtra += sizeof(i16)*nCol;
|
||||
p->aSortOrder = (u8*)pExtra;
|
||||
p->nColumn = nCol;
|
||||
@@ -2968,7 +2968,7 @@ Index *sqlite3CreateIndex(
|
||||
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;
|
||||
@@ -3249,7 +3249,7 @@ exit_create_index:
|
||||
** 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]
|
||||
@@ -3260,6 +3260,7 @@ exit_create_index:
|
||||
** are based on typical values found in actual indices.
|
||||
*/
|
||||
void sqlite3DefaultRowEst(Index *pIdx){
|
||||
#if 0
|
||||
tRowcnt *a = pIdx->aiRowEst;
|
||||
int i;
|
||||
tRowcnt n;
|
||||
@@ -3274,6 +3275,17 @@ void sqlite3DefaultRowEst(Index *pIdx){
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -1488,13 +1488,15 @@ void sqlite3Pragma(
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
10
src/select.c
10
src/select.c
@@ -1690,7 +1690,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
|
||||
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;
|
||||
@@ -3829,7 +3829,7 @@ static int withExpand(
|
||||
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;
|
||||
@@ -4005,7 +4005,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 = 1048576;
|
||||
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
|
||||
pTab->tabFlags |= TF_Ephemeral;
|
||||
#endif
|
||||
}else{
|
||||
@@ -4655,7 +4655,7 @@ int sqlite3Select(
|
||||
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);
|
||||
@@ -4686,7 +4686,7 @@ int sqlite3Select(
|
||||
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));
|
||||
|
@@ -1471,7 +1471,7 @@ struct Table {
|
||||
#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 */
|
||||
@@ -1680,7 +1680,10 @@ struct UnpackedRecord {
|
||||
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 */
|
||||
|
30
src/where.c
30
src/where.c
@@ -1956,7 +1956,8 @@ static void whereKeyStats(
|
||||
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);
|
||||
@@ -2092,7 +2093,7 @@ static int whereRangeScanEst(
|
||||
/* 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(). */
|
||||
@@ -2251,6 +2252,7 @@ static int whereInScanEst(
|
||||
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 */
|
||||
@@ -2259,14 +2261,14 @@ static int whereInScanEst(
|
||||
|
||||
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));
|
||||
}
|
||||
@@ -4059,8 +4061,7 @@ static int whereLoopAddBtreeIndex(
|
||||
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;
|
||||
@@ -4074,7 +4075,7 @@ static int whereLoopAddBtreeIndex(
|
||||
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
|
||||
@@ -4082,10 +4083,11 @@ static int whereLoopAddBtreeIndex(
|
||||
** 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;
|
||||
@@ -4093,7 +4095,7 @@ static int whereLoopAddBtreeIndex(
|
||||
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);
|
||||
@@ -4305,7 +4307,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 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 */
|
||||
@@ -4340,12 +4342,12 @@ static int whereLoopAddBtree(
|
||||
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
|
||||
@@ -4354,7 +4356,7 @@ static int whereLoopAddBtree(
|
||||
}
|
||||
pProbe = &sPk;
|
||||
}
|
||||
rSize = sqlite3LogEst(pTab->nRowEst);
|
||||
rSize = pTab->nRowLogEst;
|
||||
rLogSize = estLog(rSize);
|
||||
|
||||
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
|
||||
|
Reference in New Issue
Block a user