-C Multiply\sall\scursor\sstep\scost\sestimates\sby\sthe\sestimated\ssize\sof\sthe\srow\sin\nbytes,\sin\sorder\sto\sget\sthe\squery\splanner\sot\smake\suse\sof\sestimated\srow\ssizes.\nThis\scheck-in\suses\smagic\snumbers\sin\sa\sfew\splaces\s(for\sexample,\sestimates\sof\nthe\ssize\sof\soutput\srows)\sand\sneeds\slots\sof\srefinement.\s\sConsider\sthis\sa\nproof-of-concept\sonly.
-D 2013-10-07T17:32:15.338
+C Further\srefinement\sof\sthe\sidea\sof\smultiplying\srun-time\scost\sestimates\sby\nthe\sestimated\srow\ssize.
+D 2013-10-08T18:40:37.532
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/btree.c d5720cbb21ae56e7e5b07847e05e5b203818acac
F src/btree.h bfe0e8c5759b4ec77b0d18390064a6ef3cdffaaf
F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0
-F src/build.c ea07ec35354cdcd017b128679391320220030336
+F src/build.c 3da02c07b0f198a11ce3766cd34eac311656f1e8
F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c
F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68
F src/resolve.c 7459801d02997b07e8b8da85ef255392ba1d022b
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
-F src/select.c 13be733297f415b388444a2e296d23569cd83b8a
+F src/select.c 9d111a1adef56151b4bbddbcaea6d117d374e17d
F src/shell.c 5ee50ca3e35453bbd6ccdf1bdd0f6bbe9738e9fb
F src/sqlite.h.in ec40aa958a270416fb04b4f72210357bf163d2c5
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74
-F src/where.c ad5e680c0b95014bb9e227990d6b0efe634e7749
+F src/where.c 2a04ab5856f8c964369d181f3580a8d14e4a325c
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
F test/e_insert.test 291e056e1a442a5e5166a989a8a03a46e38225ca
F test/e_reindex.test e175794fc41f8e8aef34772e87a7d7b7a9251dd3
F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
-F test/e_select.test f2358d074bd82240bc79a8348f284a2a8909dc1f
+F test/e_select.test d3226cb94fae4af3f198e68e71f655e106d0be47
F test/e_select2.test 22c660a7becf0712c95e1ca1b2d9e716a1261460
F test/e_update.test bea00499e43ee1da77b03cdb0b20c7c864c1ec5a
F test/e_uri.test a2c92d80093a7efdcfbb11093651cbea87097b6b
F test/where7.test 5a4b0abc207d71da4deecd734ad8579e8dd40aa8
F test/where8.test 6f95896633cf2d307b5263145b942b7d33e837c6
F test/where8m.test da346596e19d54f0aba35ebade032a7c47d79739
-F test/where9.test 4f3eab951353a3ae164befc521c777dfa903e46c
+F test/where9.test 06c5f1e13168239951d2426078334d97fdf2d26f
F test/whereA.test 4d253178d135ec46d1671e440cd8f2b916aa6e6b
F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5
F test/whereC.test d6f4ecd4fa2d9429681a5b22a25d2bda8e86ab8a
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 1d7b2dc0eae70c0c0e523b715acf758bb4cfa9ac
-R b3d2afdb618d61f33659270b34382478
+P cb34cfe57c2a664fbfae8106e95114400ea222d5
+R 2b7915a92bd0315e781ed0d1390f4f69
U drh
-Z 2fed1ec905830e828c488397bcac95d0
+Z 27bbb4f4b3fe1d2932c4d2e467493b71
-cb34cfe57c2a664fbfae8106e95114400ea222d5
\ No newline at end of file
+18bd6ba96d19de6047baebfa15b1f739577c9ec4
\ No newline at end of file
pTable->iPKey = -1;
pTable->pSchema = db->aDb[iDb].pSchema;
pTable->nRef = 1;
- pTable->nRowEst = 1000000;
+ pTable->nRowEst = 1048576;
assert( pParse->pNewTable==0 );
pParse->pNewTable = pTable;
*/
static void selectAddColumnTypeAndCollation(
Parse *pParse, /* Parsing contexts */
- int nCol, /* Number of columns */
- Column *aCol, /* List of columns */
+ Table *pTab, /* Add column type information to this table */
Select *pSelect /* SELECT used to determine types and collations */
){
sqlite3 *db = pParse->db;
int i;
Expr *p;
struct ExprList_item *a;
+ u64 szAll = 0;
assert( pSelect!=0 );
assert( (pSelect->selFlags & SF_Resolved)!=0 );
- assert( nCol==pSelect->pEList->nExpr || db->mallocFailed );
+ assert( pTab->nCol==pSelect->pEList->nExpr || db->mallocFailed );
if( db->mallocFailed ) return;
memset(&sNC, 0, sizeof(sNC));
sNC.pSrcList = pSelect->pSrc;
a = pSelect->pEList->a;
- for(i=0, pCol=aCol; i<nCol; i++, pCol++){
+ for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
p = a[i].pExpr;
pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p, 0, 0, 0));
+ sqlite3AffinityType(pCol->zType, &pCol->szEst);
+ szAll += pCol->szEst;
pCol->affinity = sqlite3ExprAffinity(p);
if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_NONE;
pColl = sqlite3ExprCollSeq(pParse, p);
pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
}
}
+ pTab->szTabRow = sqlite3LogEst(szAll*4);
}
/*
assert( db->lookaside.bEnabled==0 );
pTab->nRef = 1;
pTab->zName = 0;
- pTab->nRowEst = 1000000;
+ pTab->nRowEst = 1048576;
selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
- selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSelect);
+ selectAddColumnTypeAndCollation(pParse, pTab, pSelect);
pTab->iPKey = -1;
if( db->mallocFailed ){
sqlite3DeleteTable(db, pTab);
pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
if( pTab==0 ) return WRC_Abort;
pTab->nRef = 1;
- pTab->zName = sqlite3MPrintf(db, "sqlite_subquery_%p_", (void*)pTab);
+ pTab->zName = sqlite3MPrintf(db, "sqlite_sq_%p", (void*)pTab);
while( pSel->pPrior ){ pSel = pSel->pPrior; }
selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol);
pTab->iPKey = -1;
- pTab->nRowEst = 1000000;
+ pTab->nRowEst = 1048576;
pTab->tabFlags |= TF_Ephemeral;
#endif
}else{
Select *pSel = pFrom->pSelect;
assert( pSel );
while( pSel->pPrior ) pSel = pSel->pPrior;
- selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSel);
+ selectAddColumnTypeAndCollation(pParse, pTab, pSel);
}
}
}
WhereLoopBuilder *pBuilder,
WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */
WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */
- LogEst *pnOut /* IN/OUT: Number of rows visited */
+ WhereLoop *pLoop /* Modify the .nOut and maybe .rRun fields */
){
int rc = SQLITE_OK;
- int nOut = (int)*pnOut;
+ int nOut = pLoop->nOut;
+ int nEq = pLoop->u.btree.nEq;
LogEst nNew;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
- Index *p = pBuilder->pNew->u.btree.pIndex;
- int nEq = pBuilder->pNew->u.btree.nEq;
+ Index *p = pLoop->u.btree.pIndex;
if( p->nSample>0
&& nEq==pBuilder->nRecValid
if( nNew<nOut ){
nOut = nNew;
}
- *pnOut = (LogEst)nOut;
+ pLoop->nOut = (LogEst)nOut;
WHERETRACE(0x100, ("range scan regions: %u..%u est=%d\n",
(u32)iLower, (u32)iUpper, nOut));
return SQLITE_OK;
}
if( nNew<10 ) nNew = 10;
if( nNew<nOut ) nOut = nNew;
- *pnOut = (LogEst)nOut;
+ pLoop->nOut = (LogEst)nOut;
return rc;
}
if( pNew->wsFlags & WHERE_COLUMN_RANGE ){
/* Adjust nOut and rRun for STAT3 range values */
assert( pNew->nOut==saved_nOut );
- whereRangeScanEst(pParse, pBuilder, pBtm, pTop, &pNew->nOut);
+ whereRangeScanEst(pParse, pBuilder, pBtm, pTop, pNew);
+
+ /* If the range constraint is the only constraint on the index and
+ ** if the range constraint does not reduce the search space,
+ ** then this is really just an index scan which has already
+ ** been analyzed. */
+ if( pNew->nOut>=saved_nOut && pNew->u.btree.nEq==0 ) continue;
}
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( nInMul==0
pWCEnd = pWC->a + pWC->nTerm;
pNew = pBuilder->pNew;
memset(&sSum, 0, sizeof(sSum));
+ pItem = pWInfo->pTabList->a + pNew->iTab;
+ iCur = pItem->iCursor;
for(pTerm=pWC->a; pTerm<pWCEnd && rc==SQLITE_OK; pTerm++){
if( (pTerm->eOperator & WO_OR)!=0
int once = 1;
int i, j;
- pItem = pWInfo->pTabList->a + pNew->iTab;
- iCur = pItem->iCursor;
sSubBuild = *pBuilder;
sSubBuild.pOrderBy = 0;
sSubBuild.pOrSet = &sCur;
if( pWInfo->pOrderBy==0 || nRowEst==0 ){
aFrom[0].isOrderedValid = 1;
}else{
- /* TUNING: Estimated cost of sorting is N*log2(N) where N is the
- ** number of output rows. */
+ /* TUNING: Estimated cost of sorting is 48*N*log2(N) where N is the
+ ** number of output rows. The 48 is the expected size of a row to sort.
+ ** FIXME: compute a better estimate of the 48 multiplier based on the
+ ** result set expressions. */
rSortCost = nRowEst + estLog(nRowEst) + 55;
WHERETRACE(0x002,("---- sort cost=%-3d\n", rSortCost));
}
# left-hand and right-hand datasets.
#
do_join_test e_select-1.4.2.1 {
- SELECT * FROM x2 %JOIN% x3
+ SELECT * FROM x2 %JOIN% x3 ORDER BY +c, +f
} [list -60.06 {} {} -39.24 {} encompass -1 \
- -60.06 {} {} presenting 51 reformation dignified \
- -60.06 {} {} conducting -87.24 37.56 {} \
- -60.06 {} {} coldest -96 dramatists 82.3 \
-60.06 {} {} alerting {} -93.79 {} \
+ -60.06 {} {} coldest -96 dramatists 82.3 \
+ -60.06 {} {} conducting -87.24 37.56 {} \
+ -60.06 {} {} presenting 51 reformation dignified \
-58 {} 1.21 -39.24 {} encompass -1 \
- -58 {} 1.21 presenting 51 reformation dignified \
- -58 {} 1.21 conducting -87.24 37.56 {} \
- -58 {} 1.21 coldest -96 dramatists 82.3 \
-58 {} 1.21 alerting {} -93.79 {} \
+ -58 {} 1.21 coldest -96 dramatists 82.3 \
+ -58 {} 1.21 conducting -87.24 37.56 {} \
+ -58 {} 1.21 presenting 51 reformation dignified \
]
# TODO: Come back and add a few more like the above.
OR (b NOT NULL AND c NOT NULL AND d IS NULL)
}
} {1 {no query solution}}
-ifcapable stat4||stat3 {
- # When STAT3 is enabled, the "b NOT NULL" terms get translated
- # into b>NULL, which can be satified by the index t1b. It is a very
- # expensive way to do the query, but it works, and so a solution is possible.
- do_test where9-6.8.3-stat4 {
- catchsql {
- UPDATE t1 INDEXED BY t1b SET a=a+100
- WHERE (b IS NULL AND c NOT NULL AND d NOT NULL)
- OR (b NOT NULL AND c IS NULL AND d NOT NULL)
- OR (b NOT NULL AND c NOT NULL AND d IS NULL)
- }
- } {0 {}}
- do_test where9-6.8.4-stat4 {
- catchsql {
- DELETE FROM t1 INDEXED BY t1b
- WHERE (b IS NULL AND c NOT NULL AND d NOT NULL)
- OR (b NOT NULL AND c IS NULL AND d NOT NULL)
- OR (b NOT NULL AND c NOT NULL AND d IS NULL)
- }
- } {0 {}}
-} else {
+if {1} {
do_test where9-6.8.3 {
catchsql {
UPDATE t1 INDEXED BY t1b SET a=a+100