Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a problem in calculating the costs of "OR" scans. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
9bbca48b42e4fe16f2188e18dc736da3 |
User & Date: | dan 2014-04-30 18:11:55.566 |
Context
2014-05-01
| ||
10:19 | Update a test case in wal2.test that explicitly corrupts a checksum in the wal file to account for the fact that the first byte of said checksum may initially be 0xFF. (check-in: 2b935bdea1 user: dan tags: trunk) | |
2014-04-30
| ||
20:32 | Merge in all recent changes and enhancements from trunk. (check-in: 84243f8444 user: drh tags: win32-none) | |
18:11 | Fix a problem in calculating the costs of "OR" scans. (check-in: 9bbca48b42 user: dan tags: trunk) | |
15:22 | Modify the way the costs of various query plans are estimated. If the user supplies a likelihood() value (or equivalent) on an indexed WHERE constraint, use it to estimate the number of index rows visited. (check-in: 90e3667647 user: dan tags: trunk) | |
Changes
Changes to src/where.c.
︙ | ︙ | |||
4734 4735 4736 4737 4738 4739 4740 | WhereClause *pWC; WhereLoop *pNew; WhereTerm *pTerm, *pWCEnd; int rc = SQLITE_OK; int iCur; WhereClause tempWC; WhereLoopBuilder sSubBuild; | | | 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 | WhereClause *pWC; WhereLoop *pNew; WhereTerm *pTerm, *pWCEnd; int rc = SQLITE_OK; int iCur; WhereClause tempWC; WhereLoopBuilder sSubBuild; WhereOrSet sSum, sCur; struct SrcList_item *pItem; pWC = pBuilder->pWC; if( pWInfo->wctrlFlags & WHERE_AND_ONLY ) return SQLITE_OK; pWCEnd = pWC->a + pWC->nTerm; pNew = pBuilder->pNew; memset(&sSum, 0, sizeof(sSum)); |
︙ | ︙ | |||
4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 | if( sCur.n==0 ){ sSum.n = 0; break; }else if( once ){ whereOrMove(&sSum, &sCur); once = 0; }else{ whereOrMove(&sPrev, &sSum); sSum.n = 0; for(i=0; i<sPrev.n; i++){ for(j=0; j<sCur.n; j++){ whereOrInsert(&sSum, sPrev.a[i].prereq | sCur.a[j].prereq, sqlite3LogEstAdd(sPrev.a[i].rRun, sCur.a[j].rRun), sqlite3LogEstAdd(sPrev.a[i].nOut, sCur.a[j].nOut)); } } } } pNew->nLTerm = 1; pNew->aLTerm[0] = pTerm; pNew->wsFlags = WHERE_MULTI_OR; pNew->rSetup = 0; pNew->iSortIdx = 0; memset(&pNew->u, 0, sizeof(pNew->u)); for(i=0; rc==SQLITE_OK && i<sSum.n; i++){ | > > > > > > > > > > > > > | | 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 | if( sCur.n==0 ){ sSum.n = 0; break; }else if( once ){ whereOrMove(&sSum, &sCur); once = 0; }else{ WhereOrSet sPrev; whereOrMove(&sPrev, &sSum); sSum.n = 0; for(i=0; i<sPrev.n; i++){ for(j=0; j<sCur.n; j++){ whereOrInsert(&sSum, sPrev.a[i].prereq | sCur.a[j].prereq, sqlite3LogEstAdd(sPrev.a[i].rRun, sCur.a[j].rRun), sqlite3LogEstAdd(sPrev.a[i].nOut, sCur.a[j].nOut)); } } } } pNew->nLTerm = 1; pNew->aLTerm[0] = pTerm; pNew->wsFlags = WHERE_MULTI_OR; pNew->rSetup = 0; pNew->iSortIdx = 0; memset(&pNew->u, 0, sizeof(pNew->u)); for(i=0; rc==SQLITE_OK && i<sSum.n; i++){ /* TUNING: Currently sSum.a[i].rRun is set to the sum of the costs ** of all sub-scans required by the OR-scan. However, due to rounding ** errors, it may be that the cost of the OR-scan is equal to its ** most expensive sub-scan. Add the smallest possible penalty ** (equivalent to multiplying the cost by 1.07) to ensure that ** this does not happen. Otherwise, for WHERE clauses such as the ** following where there is an index on "y": ** ** WHERE likelihood(x=?, 0.99) OR y=? ** ** the planner may elect to "OR" together a full-table scan and an ** index lookup. And other similarly odd results. */ pNew->rRun = sSum.a[i].rRun + 1; pNew->nOut = sSum.a[i].nOut; pNew->prereq = sSum.a[i].prereq; rc = whereLoopInsert(pBuilder, pNew); } } } return rc; |
︙ | ︙ |
Changes to test/cost.test.
︙ | ︙ | |||
146 147 148 149 150 151 152 | ORDER BY a } { 0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)} 0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)} 0 0 0 {USE TEMP B-TREE FOR ORDER BY} } | < > > > > > > | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | ORDER BY a } { 0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)} 0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)} 0 0 0 {USE TEMP B-TREE FOR ORDER BY} } do_eqp_test 7.3 { SELECT rowid FROM t1 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 0 0 {SCAN TABLE t1} } do_eqp_test 7.4 { SELECT rowid FROM t1 WHERE (+b IS NULL AND c NOT NULL) OR c IS NULL } { 0 0 0 {SCAN TABLE t1} } #------------------------------------------------------------------------- # reset_db do_execsql_test 8.1 { CREATE TABLE composer( cid INTEGER PRIMARY KEY, |
︙ | ︙ |