Confirmed
3.6.23.1
sqlite> select count(*) from object_formats join page_table on
page_table.version=3 and page_table.objectid = object_formats.objectid ;
12366
CPU Time: user 0.019997 sys 0.003000
3.7.0
CPU Time: user 32.269095 sys 0.019997
3.7.2
CPU Time: user 33.606891 sys 0.001000
Fossil repository as of 9/25/2010
CPU Time: user 31.087274 sys 0.001000
So...apparently still a bug....
The plan is different:
Slow version:
0|Trace|0|0|0||00|
1|Null|0|1|0||00|
2|Integer|3|2|0||00|
3|Goto|0|22|0||00|
4|OpenRead|0|5|0|2|00|
5|OpenRead|2|9|0|keyinfo(3,BINARY,BINARY)|00|
6|Rewind|0|16|0||00|
7|SCopy|2|3|0||00|
8|Column|0|1|4||00|
9|IsNull|4|15|0||00|
10|Affinity|4|1|0|d|00|
11|SeekGe|2|15|3|2|00|
12|IdxGE|2|15|3|2|01|
13|AggStep|0|0|1|count(0)|00|
14|Next|2|12|0||00|
15|Next|0|7|0||01|
16|Close|0|0|0||00|
17|Close|2|0|0||00|
18|AggFinal|1|0|0|count(0)|00|
19|SCopy|1|6|0||00|
20|ResultRow|6|1|0||00|
21|Halt|0|0|0||00|
22|Transaction|0|0|0||00|
23|VerifyCookie|0|15|0||00|
24|TableLock|0|5|0|object_formats|00|
25|TableLock|0|2|0|page_table|00|
26|Goto|0|4|0||00|
Fast version:
0|Trace|0|0|0||00|
1|Null|0|1|0||00|
2|Integer|3|2|0||00|
3|Goto|0|21|0||00|
4|OpenRead|2|9|0|keyinfo(3,BINARY,BINARY)|00|
5|OpenRead|0|5|0|2|00|
6|SeekGe|2|15|2|1|00|
7|IdxGE|2|15|2|1|01|
8|Rewind|0|14|0||00|
9|Column|2|1|3||00|
10|Column|0|1|4||00|
11|Ne|4|13|3|collseq(BINARY)|6b|
12|AggStep|0|0|1|count(0)|00|
13|Next|0|9|0||01|
14|Next|2|7|0||00|
15|Close|2|0|0||00|
16|Close|0|0|0||00|
17|AggFinal|1|0|0|count(0)|00|
18|SCopy|1|5|0||00|
19|ResultRow|5|1|0||00|
20|Halt|0|0|0||00|
21|Transaction|0|0|0||00|
22|VerifyCookie|0|15|0||00|
23|TableLock|0|2|0|page_table|00|
24|TableLock|0|5|0|object_formats|00|
25|Goto|0|4|0||00|
Bug was introduced on "fossil update 2010-04-16"
633c633
< #define SQLITE_SOURCE_ID "2010-04-14 19:01:45
b87cb0c2bd9c52a938795a974e101879b81210e3"
---
> #define SQLITE_SOURCE_ID "2010-04-15 23:24:29
> f96782b389b5b97b488dc5814f7082e0393f64cd"
83092,83093c83092,83093
< ** subquery does not have both an ORDER BY and a LIMIT clause.
< ** (See ticket #2339)
---
> ** subquery does not have a LIMIT clause.
> ** (See ticket #2339 and ticket [02a8e81d44]).
83176c83176
< if( p->pRightmost && pSub->pLimit && pSub->pOrderBy ){
---
> if( p->pRightmost && pSub->pLimit ){
89670a89671,89675
> /* No OR-clause optimization allowed if the NOT INDEXED clause is used */
> if( pSrc->notIndexed ){
> return;
> }
>
89712a89718,89719
> WHERETRACE(("... sorting increases OR cost %.9g to %.9g\n",
> rTotal, rTotal+nRow*estLog(nRow)));
89714d89720
< WHERETRACE(("... sorting increases OR cost to %.9g\n", rTotal));
90665c90671
< ** nBound:
---
> ** estBound:
90672c90678
< ** nBound to 33. Two constraints (x>? AND x<?) reduce nBound to 11.
---
> ** estBound to 33. Two constraints (x>? AND x<?) reduce estBound to
> 11.
90694c90700,90701
< int nBound = 100;
---
> int estBound = 100;
> int nBound = 0; /* Number of range constraints seen */
90720c90727
< /* Determine the value of nBound. */
---
> /* Determine the value of estBound. */
90726c90733
< whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &nBound);
---
> whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &estBound);
90727a90735
> nBound = 1;
90731a90740
> nBound++;
90800,90801c90809,90810
< nRow = (nRow * (double)nBound) / (double)100;
< cost = (cost * (double)nBound) / (double)100;
---
> nRow = (nRow * (double)estBound) / (double)100;
> cost = (cost * (double)estBound) / (double)100;
90823,90827c90832,90849
< */
< if( nRow>2 && cost<=pCost->rCost ){
< int k;
< int nSkip = nEq;
< Bitmask thisTab = getMask(pWC->pMaskSet, iCur);
---
> ** Also, never reduce the output row count below 2 using this step.
> **
> ** Do not reduce the output row count if pSrc is the only table that
> ** is notReady; if notReady is a power of two. This will be the case
> ** when the main sqlite3WhereBegin() loop is scanning for a table with
> ** and "optimal" index, and on such a scan the output row count
> ** reduction is not valid because it does not update the "pCost->used"
> ** bitmap. The notReady bitmap will also be a power of two when we
> ** are scanning for the last table in a 64-way join. We are willing
> ** to bypass this optimization in that corner case.
> */
> if( nRow>2 && cost<=pCost->rCost && (notReady & (notReady-1))!=0 ){
> int k; /* Loop counter */
> int nSkipEq = nEq; /* Number of == constraints to skip */
> int nSkipRange = nBound; /* Number of <
>
> thisTab = getMask(pWC->pMaskSet, iCur);
90832c90854
< if( nSkip ){
---
> if( nSkipEq ){
90835c90857
< nSkip--;
---
> nSkipEq--;
90840a90863,90872
> }else if( pTerm->eOperator & (WO_LT|WO_LE|WO_GT|WO_GE) ){
> if( nSkipRange ){
> /* Ignore the first nBound range constraints since the index
> ** has already accounted for these */
> nSkipRange--;
> }else{
> /* Assume each additional range constraint reduces the result
> ** set size by a factor of 3 */
> nRow /= 3;
> }
90851c90883
< "%s(%s): nEq=%d nInMul=%d nBound=%d bSort=%d bLookup=%d wsFlags=0x%x\n"
---
> "%s(%s): nEq=%d nInMul=%d estBound=%d bSort=%d bLookup=%d
> wsFlags=0x%x\n"
90854c90886,90887
< nEq, nInMul, nBound, bSort, bLookup, wsFlags, notReady, nRow, cost, used
---
> nEq, nInMul, estBound, bSort, bLookup, wsFlags,
> notReady, nRow, cost, used
90861c90894
< && (cost<pCost->rCost || (cost==pCost->rCost && nRow<pCost->nRow))
---
> && (cost<pCost->rCost || (cost<=pCost->rCost && nRow<pCost->nRow))
92111c92144
< ** next nested loop. The FROM clause entries may be iterated through
---
> ** next nested loop. The loop tests all FROM clause entries
92114,92115c92147,92149
< ** The first iteration, which is always performed, searches for the
< ** FROM clause entry that permits the lowest-cost, "optimal" scan. In
---
> ** The first test is always performed if there are two or more entries
> ** remaining and never performed if there is only one FROM clause entry
> ** to choose from. The first test looks for an "optimal" scan. In
92120c92154,92158
< ** by waiting for other tables to run first.
---
> ** by waiting for other tables to run first. This "optimal" test works
> ** by first assuming that the FROM clause is on the inner loop and finding
> ** its query plan, then checking to see if that query plan uses any
> ** other FROM clause terms that are notReady. If no notReady terms are
> ** used then the "optimal" query plan works.
92122,92124c92160,92162
< ** The second iteration is only performed if no optimal scan strategies
< ** were found by the first. This iteration is used to search for the
< ** lowest cost scan overall.
---
> ** The second loop iteration is only performed if no optimal scan
> ** strategies were found by the first loop. This 2nd iteration is used to
> ** search for the lowest cost scan overall.
92142,92144c92180,92181
< for(isOptimal=1; isOptimal>=0 && bestJ<0; isOptimal--){
< Bitmask mask = (isOptimal ? 0 : notReady);
< assert( (nTabList-iFrom)>1 || isOptimal );
---
> for(isOptimal=(iFrom<nTabList-1); isOptimal>=0; isOptimal--){
> Bitmask mask; /* Mask of tables not yet ready */
92156a92194
> mask = (isOptimal ? m : notReady);
92172,92173c92210,92211
< && (j==iFrom || sCost.rCost<bestPlan.rCost
< || (sCost.rCost==bestPlan.rCost && sCost.nRow<bestPlan.nRow))
---
> && (bestJ<0 || sCost.rCost<bestPlan.rCost
> || (sCost.rCost<=bestPlan.rCost && sCost.nRow<bestPlan.nRow))
92174a92213,92214
> WHERETRACE(("... best so far with cost=%g and nRow=%g\n",
> sCost.rCost, sCost.nRow));
Michael D. Black
Senior Scientist
Advanced Analytics Directorate
Northrop Grumman Information Systems
________________________________
From: [email protected] on behalf of Charles Samuels
Sent: Fri 9/24/2010 7:03 PM
To: [email protected]
Subject: EXTERNAL:[sqlite] Massive performance regression in 3.7.x
Greetings,
With the sqlite database here:
http://www.derkarl.org/~charles/massive_performance_regression.bz2
There is a massive performance regression between 3.7.1 and 3.7.2, when
compared to 3.6.23.1.
The following query runs orders of magnitude slower than it did in the
previous version:
select *
from object_formats join
page_table on page_table.version=3 and page_table.objectid =
object_formats.objectid ;
Thanks,
Charles
_______________________________________________
sqlite-users mailing list
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
_______________________________________________
sqlite-users mailing list
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users