Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch query-planner-fix Excluding Merge-Ins
This is equivalent to a diff from 36b7c5ce to 43c59c85
2014-08-08
| ||
17:49 | Improvements to the way the query planner handles sorting costs, so that very large sorting costs do not overwhelm the loop costs. (check-in: bdaa6947 user: drh tags: trunk) | |
17:25 | Fix a buffer overrun in the previous commit. (Closed-Leaf check-in: 43c59c85 user: dan tags: query-planner-fix) | |
16:52 | Because SQLite internally calculates query plan costs using a logarithmic scale, very large estimated sorting costs can cause all other estimated costs to be rounded down to zero. In these cases break ties between plans with the same total cost by comparing the costs with sorting excluded. This is an alternative fix for the problem addressed by [2af630c572]. (check-in: 299b9570 user: dan tags: query-planner-fix) | |
15:38 | The SQLITE_IOERR_BLOCKED extended error code is not longer used, so remove assert() statements and documentation for that error code. Also make other documentation improvements. (check-in: 36b7c5ce user: drh tags: trunk) | |
12:51 | Reworking the documentation on integer result codes. This is a comment and documentation change only. There are no changes to code. (check-in: 54f1df7b user: drh tags: trunk) | |
Changes to src/where.c.
︙ | |||
5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 | 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | int i; for(i=0; i<nLoop; i++){ zName[i] = pPath->aLoop[i]->cId; } if( pLast ) zName[i++] = pLast->cId; zName[i] = 0; return zName; } #endif /* ** Return the cost of sorting nRow rows, assuming that the keys have ** nOrderby columns and that the first nSorted columns are already in ** order. */ static LogEst whereSortingCost( WhereInfo *pWInfo, LogEst nRow, int nOrderBy, int nSorted ){ /* TUNING: Estimated cost of a full external sort, where N is ** the number of rows to sort is: ** ** cost = (3.0 * N * log(N)). ** ** Or, if the order-by clause has X terms but only the last Y ** terms are out of order, then block-sorting will reduce the ** sorting cost to: ** ** cost = (3.0 * N * log(N)) * (Y/X) ** ** The (Y/X) term is implemented using stack variable rScale ** below. */ LogEst rScale, rSortCost; assert( nOrderBy>0 && 66==sqlite3LogEst(100) ); rScale = sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66; rSortCost = nRow + estLog(nRow) + rScale + 16; /* TUNING: The cost of implementing DISTINCT using a B-TREE is ** similar but with a larger constant of proportionality. ** Multiply by an additional factor of 3.0. */ if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){ rSortCost += 16; } return rSortCost; } /* ** Given the list of WhereLoop objects at pWInfo->pLoops, this routine ** attempts to find the lowest cost path that visits each WhereLoop ** once. This path is then loaded into the pWInfo->a[].pWLoop fields. ** ** Assume that the total number of output rows that will need to be sorted |
︙ | |||
5417 5418 5419 5420 5421 5422 5423 | 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 | - - - + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + - + + + + - - - + + + - - + + + + + - + - - - - - - - - - - - - - - + - - - - + + + + - - - - - - - - - - - - + + + + + + + + + - - - + | int nLoop; /* Number of terms in the join */ Parse *pParse; /* Parsing context */ sqlite3 *db; /* The database connection */ int iLoop; /* Loop counter over the terms of the join */ int ii, jj; /* Loop counters */ int mxI = 0; /* Index of next entry to replace */ int nOrderBy; /* Number of ORDER BY clause terms */ |
︙ | |||
5548 5549 5550 5551 5552 5553 5554 | 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 | - + | testcase( jj==nTo-1 ); break; } } if( jj>=nTo ){ /* None of the existing best-so-far paths match the candidate. */ if( nTo>=mxChoice |
︙ | |||
5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 | 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 | + - + - + + + - + | #endif } /* pWLoop is a winner. Add it to the set of best so far */ pTo->maskLoop = pFrom->maskLoop | pWLoop->maskSelf; pTo->revLoop = revMask; pTo->nRow = nOut; pTo->rCost = rCost; pTo->rUnsorted = rUnsorted; pTo->isOrdered = isOrdered; memcpy(pTo->aLoop, pFrom->aLoop, sizeof(WhereLoop*)*iLoop); pTo->aLoop[iLoop] = pWLoop; if( nTo>=mxChoice ){ mxI = 0; mxCost = aTo[0].rCost; |
︙ |
Changes to src/whereInt.h.
︙ | |||
179 180 181 182 183 184 185 186 187 188 189 190 191 192 | 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | + | ** at the end is the choosen query plan. */ struct WherePath { Bitmask maskLoop; /* Bitmask of all WhereLoop objects in this path */ Bitmask revLoop; /* aLoop[]s that should be reversed for ORDER BY */ LogEst nRow; /* Estimated number of rows generated by this path */ LogEst rCost; /* Total cost of this path */ LogEst rUnsorted; /* Total cost of this path ignoring sorting costs */ i8 isOrdered; /* No. of ORDER BY terms satisfied. -1 for unknown */ WhereLoop **aLoop; /* Array of WhereLoop objects implementing this path */ }; /* ** The query generator uses an array of instances of this structure to ** help it analyze the subexpressions of the WHERE clause. Each WHERE |
︙ |