Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a161c222a6 |
@@ -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
@@ -1 +1 @@
|
||||
1d7b2dc0eae70c0c0e523b715acf758bb4cfa9ac
|
||||
8e78557a40a6b97009852f5b72e68d6483fb00fc
|
||||
+15
-15
@@ -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
@@ -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
@@ -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
@@ -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 */
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user