Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Performance optimizations in the VDBE and especially to the OP_Next and related opcodes. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | toTypeFuncs |
Files: | files | file ages | folders |
SHA1: |
d78c5d89de4b840351b026c9db1952fc |
User & Date: | drh 2013-08-20 00:42:11.120 |
References
2013-08-20
| ||
03:13 | Performance optimizations in the VDBE and especially to the OP_Next and related opcodes and in the sqlite3BtreeNext() and sqlite3BtreePrevious() routines. This is a cherrypick of [6f99b54aedeb], [d2efea1682a7], and [d78c5d89de4b]. (check-in: 7f72fc4f47 user: drh tags: trunk) | |
Context
2013-08-20
| ||
03:13 | Performance optimizations in the VDBE and especially to the OP_Next and related opcodes and in the sqlite3BtreeNext() and sqlite3BtreePrevious() routines. This is a cherrypick of [6f99b54aedeb], [d2efea1682a7], and [d78c5d89de4b]. (check-in: 7f72fc4f47 user: drh tags: trunk) | |
02:07 | Fix compiler warnings and boundary cases for the tointeger() and toreal() functions. (check-in: 4438b98658 user: drh tags: toTypeFuncs) | |
00:42 | Performance optimizations in the VDBE and especially to the OP_Next and related opcodes. (check-in: d78c5d89de user: drh tags: toTypeFuncs) | |
2013-08-19
| ||
23:18 | Performance improvement to SQL function calls in the VDBE. (check-in: d2efea1682 user: drh tags: toTypeFuncs) | |
Changes
Changes to src/btree.c.
︙ | ︙ | |||
4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 | assert( cursorHoldsMutex(pCur) ); assert( pRes!=0 ); assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); if( pCur->eState!=CURSOR_VALID ){ rc = restoreCursorPosition(pCur); if( rc!=SQLITE_OK ){ return rc; } if( CURSOR_INVALID==pCur->eState ){ *pRes = 1; return SQLITE_OK; } if( pCur->skipNext ){ | > | 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 | assert( cursorHoldsMutex(pCur) ); assert( pRes!=0 ); assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); if( pCur->eState!=CURSOR_VALID ){ rc = restoreCursorPosition(pCur); if( rc!=SQLITE_OK ){ *pRes = 0; return rc; } if( CURSOR_INVALID==pCur->eState ){ *pRes = 1; return SQLITE_OK; } if( pCur->skipNext ){ |
︙ | ︙ | |||
4834 4835 4836 4837 4838 4839 4840 | testcase( idx>pPage->nCell ); pCur->info.nSize = 0; pCur->validNKey = 0; if( idx>=pPage->nCell ){ if( !pPage->leaf ){ rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8])); | | > > > | 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 | testcase( idx>pPage->nCell ); pCur->info.nSize = 0; pCur->validNKey = 0; if( idx>=pPage->nCell ){ if( !pPage->leaf ){ rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8])); if( rc ){ *pRes = 0; return rc; } rc = moveToLeftmost(pCur); *pRes = 0; return rc; } do{ if( pCur->iPage==0 ){ *pRes = 1; |
︙ | ︙ | |||
4882 4883 4884 4885 4886 4887 4888 | assert( cursorHoldsMutex(pCur) ); assert( pRes!=0 ); assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); pCur->atLast = 0; if( pCur->eState!=CURSOR_VALID ){ if( ALWAYS(pCur->eState>=CURSOR_REQUIRESEEK) ){ rc = btreeRestoreCursorPosition(pCur); | | > > > | 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 | assert( cursorHoldsMutex(pCur) ); assert( pRes!=0 ); assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); pCur->atLast = 0; if( pCur->eState!=CURSOR_VALID ){ if( ALWAYS(pCur->eState>=CURSOR_REQUIRESEEK) ){ rc = btreeRestoreCursorPosition(pCur); if( rc!=SQLITE_OK ){ *pRes = 0; return rc; } } if( CURSOR_INVALID==pCur->eState ){ *pRes = 1; return SQLITE_OK; } if( pCur->skipNext ){ assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT ); |
︙ | ︙ | |||
4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 | pPage = pCur->apPage[pCur->iPage]; assert( pPage->isInit ); if( !pPage->leaf ){ int idx = pCur->aiIdx[pCur->iPage]; rc = moveToChild(pCur, get4byte(findCell(pPage, idx))); if( rc ){ return rc; } rc = moveToRightmost(pCur); }else{ while( pCur->aiIdx[pCur->iPage]==0 ){ if( pCur->iPage==0 ){ pCur->eState = CURSOR_INVALID; | > | 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 | pPage = pCur->apPage[pCur->iPage]; assert( pPage->isInit ); if( !pPage->leaf ){ int idx = pCur->aiIdx[pCur->iPage]; rc = moveToChild(pCur, get4byte(findCell(pPage, idx))); if( rc ){ *pRes = 0; return rc; } rc = moveToRightmost(pCur); }else{ while( pCur->aiIdx[pCur->iPage]==0 ){ if( pCur->iPage==0 ){ pCur->eState = CURSOR_INVALID; |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
584 585 586 587 588 589 590 | p->pResultSet = 0; db->busyHandler.nBusy = 0; CHECK_FOR_INTERRUPT; sqlite3VdbeIOTraceSql(p); #ifndef SQLITE_OMIT_PROGRESS_CALLBACK if( db->xProgress ){ assert( 0 < db->nProgressOps ); | | | 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 | p->pResultSet = 0; db->busyHandler.nBusy = 0; CHECK_FOR_INTERRUPT; sqlite3VdbeIOTraceSql(p); #ifndef SQLITE_OMIT_PROGRESS_CALLBACK if( db->xProgress ){ assert( 0 < db->nProgressOps ); nProgressLimit = (unsigned)p->aCounter[SQLITE_STMTSTATUS_VM_STEP]; if( nProgressLimit==0 ){ nProgressLimit = db->nProgressOps; }else{ nProgressLimit %= (unsigned)db->nProgressOps; } } #endif |
︙ | ︙ | |||
1844 1845 1846 1847 1848 1849 1850 | res = 1; /* Results are not equal */ } }else{ /* SQLITE_NULLEQ is clear and at least one operand is NULL, ** then the result is always NULL. ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. */ | | > > < < | 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 | res = 1; /* Results are not equal */ } }else{ /* SQLITE_NULLEQ is clear and at least one operand is NULL, ** then the result is always NULL. ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. */ if( pOp->p5 & SQLITE_JUMPIFNULL ){ pc = pOp->p2-1; }else if( pOp->p5 & SQLITE_STOREP2 ){ pOut = &aMem[pOp->p2]; MemSetTypeFlag(pOut, MEM_Null); REGISTER_TRACE(pOp->p2, pOut); } break; } }else{ /* Neither operand is NULL. Do a comparison. */ affinity = pOp->p5 & SQLITE_AFF_MASK; if( affinity ){ |
︙ | ︙ | |||
4434 4435 4436 4437 4438 4439 4440 | */ case OP_SorterSort: /* jump */ case OP_Sort: { /* jump */ #ifdef SQLITE_TEST sqlite3_sort_count++; sqlite3_search_count--; #endif | | | 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 | */ case OP_SorterSort: /* jump */ case OP_Sort: { /* jump */ #ifdef SQLITE_TEST sqlite3_sort_count++; sqlite3_search_count--; #endif p->aCounter[SQLITE_STMTSTATUS_SORT]++; /* Fall through into OP_Rewind */ } /* Opcode: Rewind P1 P2 * * * ** ** The next use of the Rowid or Column or Next instruction for P1 ** will refer to the first entry in the database table or index. ** If the table or index is empty and P2>0, then jump immediately to P2. |
︙ | ︙ | |||
4513 4514 4515 4516 4517 4518 4519 | case OP_SorterNext: /* jump */ case OP_Prev: /* jump */ case OP_Next: { /* jump */ VdbeCursor *pC; int res; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | | | | | 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 | case OP_SorterNext: /* jump */ case OP_Prev: /* jump */ case OP_Next: { /* jump */ VdbeCursor *pC; int res; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p5<ArraySize(p->aCounter) ); pC = p->apCsr[pOp->p1]; if( pC==0 ){ break; /* See ticket #2273 */ } assert( pC->isSorter==(pOp->opcode==OP_SorterNext) ); if( isSorter(pC) ){ assert( pOp->opcode==OP_SorterNext ); rc = sqlite3VdbeSorterNext(db, pC, &res); }else{ /* res = 1; // Always initialized by the xAdvance() call */ assert( pC->deferredMoveto==0 ); assert( pC->pCursor ); assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); rc = pOp->p4.xAdvance(pC->pCursor, &res); } pC->nullRow = (u8)res; pC->cacheStatus = CACHE_STALE; if( res==0 ){ pc = pOp->p2 - 1; p->aCounter[pOp->p5]++; #ifdef SQLITE_TEST sqlite3_search_count++; #endif } pC->rowidIsValid = 0; goto check_for_interrupt; } |
︙ | ︙ | |||
6237 6238 6239 6240 6241 6242 6243 | /* This is the only way out of this procedure. We have to ** release the mutexes on btrees that were acquired at the ** top. */ vdbe_return: db->lastRowid = lastRowid; testcase( nVmStep>0 ); | | | 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249 6250 6251 | /* This is the only way out of this procedure. We have to ** release the mutexes on btrees that were acquired at the ** top. */ vdbe_return: db->lastRowid = lastRowid; testcase( nVmStep>0 ); p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep; sqlite3VdbeLeave(p); return rc; /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH ** is encountered. */ too_big: |
︙ | ︙ |
Changes to src/vdbeInt.h.
︙ | ︙ | |||
342 343 344 345 346 347 348 | bft bIsReader:1; /* True for statements that read */ bft isPrepareV2:1; /* True if prepared with prepare_v2() */ bft doingRerun:1; /* True if rerunning after an auto-reprepare */ int nChange; /* Number of db changes made since last reset */ yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ yDbMask lockMask; /* Subset of btreeMask that requires a lock */ int iStatement; /* Statement number (or 0 if has not opened stmt) */ | | | 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 | bft bIsReader:1; /* True for statements that read */ bft isPrepareV2:1; /* True if prepared with prepare_v2() */ bft doingRerun:1; /* True if rerunning after an auto-reprepare */ int nChange; /* Number of db changes made since last reset */ yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ yDbMask lockMask; /* Subset of btreeMask that requires a lock */ int iStatement; /* Statement number (or 0 if has not opened stmt) */ u32 aCounter[5]; /* Counters used by sqlite3_stmt_status() */ #ifndef SQLITE_OMIT_TRACE i64 startTime; /* Time when query started - used for profiling */ #endif i64 nFkConstraint; /* Number of imm. FK constraints this VM */ i64 nStmtDefCons; /* Number of def. constraints when stmt started */ i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */ char *zSql; /* Text of the SQL statement that generated this */ |
︙ | ︙ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
1294 1295 1296 1297 1298 1299 1300 | } /* ** Return the value of a status counter for a prepared statement */ int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){ Vdbe *pVdbe = (Vdbe*)pStmt; | | | | | 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 | } /* ** Return the value of a status counter for a prepared statement */ int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){ Vdbe *pVdbe = (Vdbe*)pStmt; u32 v = pVdbe->aCounter[op]; if( resetFlag ) pVdbe->aCounter[op] = 0; return (int)v; } |