/ Check-in [f13d6ba8]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Minor performance enhancements to SQLITE_ENABLE_STMT_SCANSTATUS code.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | scanstatus
Files: files | file ages | folders
SHA1:f13d6ba8a72d75838c4aaf85326c1129da027f8b
User & Date: dan 2014-11-01 21:00:04
Context
2014-11-03
11:25
Remove unused variable from struct WhereInfo. Add some explanatory comments to new code. check-in: f5313e0c user: dan tags: scanstatus
2014-11-01
21:00
Minor performance enhancements to SQLITE_ENABLE_STMT_SCANSTATUS code. check-in: f13d6ba8 user: dan tags: scanstatus
20:38
If SQLITE_ENABLE_STMT_SCANSTATUS is defined, record the number of times each VDBE opcode is executed. Derive the values returned by sqlite3_stmt_scanstatus() from these records on demand. check-in: 9ea37422 user: dan tags: scanstatus
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

   605    605       if( db->mallocFailed ) goto no_mem;
   606    606   #ifdef VDBE_PROFILE
   607    607       start = sqlite3Hwtime();
   608    608   #endif
   609    609       nVmStep++;
   610    610       pOp = &aOp[pc];
   611    611   #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
   612         -    if( p->pFrame==0 ) p->anExec[pc]++;
          612  +    if( p->anExec ) p->anExec[pc]++;
   613    613   #endif
   614    614   
   615    615       /* Only allow tracing if SQLITE_DEBUG is defined.
   616    616       */
   617    617   #ifdef SQLITE_DEBUG
   618    618       if( db->flags & SQLITE_VdbeTrace ){
   619    619         sqlite3VdbePrintOp(stdout, pc, pOp);
................................................................................
  5405   5405       pFrame->apCsr = p->apCsr;
  5406   5406       pFrame->nCursor = p->nCursor;
  5407   5407       pFrame->aOp = p->aOp;
  5408   5408       pFrame->nOp = p->nOp;
  5409   5409       pFrame->token = pProgram->token;
  5410   5410       pFrame->aOnceFlag = p->aOnceFlag;
  5411   5411       pFrame->nOnceFlag = p->nOnceFlag;
         5412  +    pFrame->anExec = p->anExec;
  5412   5413   
  5413   5414       pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem];
  5414   5415       for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){
  5415   5416         pMem->flags = MEM_Undefined;
  5416   5417         pMem->db = db;
  5417   5418       }
  5418   5419     }else{
................................................................................
  5433   5434     p->nMem = pFrame->nChildMem;
  5434   5435     p->nCursor = (u16)pFrame->nChildCsr;
  5435   5436     p->apCsr = (VdbeCursor **)&aMem[p->nMem+1];
  5436   5437     p->aOp = aOp = pProgram->aOp;
  5437   5438     p->nOp = pProgram->nOp;
  5438   5439     p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor];
  5439   5440     p->nOnceFlag = pProgram->nOnce;
         5441  +  p->anExec = 0;
  5440   5442     pc = -1;
  5441   5443     memset(p->aOnceFlag, 0, p->nOnceFlag);
  5442   5444   
  5443   5445     break;
  5444   5446   }
  5445   5447   
  5446   5448   /* Opcode: Param P1 P2 * * *

Changes to src/vdbeInt.h.

   128    128   ** set to NULL if the currently executing frame is the main program.
   129    129   */
   130    130   typedef struct VdbeFrame VdbeFrame;
   131    131   struct VdbeFrame {
   132    132     Vdbe *v;                /* VM this frame belongs to */
   133    133     VdbeFrame *pParent;     /* Parent of this frame, or NULL if parent is main */
   134    134     Op *aOp;                /* Program instructions for parent frame */
          135  +  i64 *anExec;            /* Event counters from parent frame */
   135    136     Mem *aMem;              /* Array of memory cells for parent frame */
   136    137     u8 *aOnceFlag;          /* Array of OP_Once flags for parent frame */
   137    138     VdbeCursor **apCsr;     /* Array of Vdbe cursors for parent frame */
   138    139     void *token;            /* Copy of SubProgram.token */
   139    140     i64 lastRowid;          /* Last insert rowid (sqlite3.lastRowid) */
   140    141     int nCursor;            /* Number of entries in apCsr */
   141    142     int pc;                 /* Program Counter in parent (calling) frame */

Changes to src/vdbeaux.c.

  1719   1719       p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte);
  1720   1720       p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte);
  1721   1721       p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte);
  1722   1722       p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte);
  1723   1723       p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*),
  1724   1724                             &zCsr, zEnd, &nByte);
  1725   1725       p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, &zCsr, zEnd, &nByte);
         1726  +    p->anExec = allocSpace(p->anExec, p->nOp*sizeof(i64), &zCsr, zEnd, &nByte);
  1726   1727       if( nByte ){
  1727   1728         p->pFree = sqlite3DbMallocZero(db, nByte);
  1728   1729       }
  1729   1730       zCsr = p->pFree;
  1730   1731       zEnd = &zCsr[nByte];
  1731   1732     }while( nByte && !db->mallocFailed );
  1732   1733   
  1733         -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
  1734         -    p->anExec = (i64*)sqlite3DbMallocZero(db, p->nOp*sizeof(i64));
  1735         -#endif
  1736         -
  1737   1734     p->nCursor = nCursor;
  1738   1735     p->nOnceFlag = nOnce;
  1739   1736     if( p->aVar ){
  1740   1737       p->nVar = (ynVar)nVar;
  1741   1738       for(n=0; n<nVar; n++){
  1742   1739         p->aVar[n].flags = MEM_Null;
  1743   1740         p->aVar[n].db = db;
................................................................................
  1790   1787   /*
  1791   1788   ** Copy the values stored in the VdbeFrame structure to its Vdbe. This
  1792   1789   ** is used, for example, when a trigger sub-program is halted to restore
  1793   1790   ** control to the main program.
  1794   1791   */
  1795   1792   int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
  1796   1793     Vdbe *v = pFrame->v;
         1794  +  v->anExec = pFrame->anExec;
  1797   1795     v->aOnceFlag = pFrame->aOnceFlag;
  1798   1796     v->nOnceFlag = pFrame->nOnceFlag;
  1799   1797     v->aOp = pFrame->aOp;
  1800   1798     v->nOp = pFrame->nOp;
  1801   1799     v->aMem = pFrame->aMem;
  1802   1800     v->nMem = pFrame->nMem;
  1803   1801     v->apCsr = pFrame->apCsr;
................................................................................
  2714   2712     }
  2715   2713     for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
  2716   2714     vdbeFreeOpArray(db, p->aOp, p->nOp);
  2717   2715     sqlite3DbFree(db, p->aColName);
  2718   2716     sqlite3DbFree(db, p->zSql);
  2719   2717     sqlite3DbFree(db, p->pFree);
  2720   2718   #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
  2721         -  sqlite3DbFree(db, p->anExec);
  2722   2719     for(i=0; i<p->nScan; i++){
  2723   2720       sqlite3DbFree(db, p->aScan[i].zName);
  2724   2721     }
  2725   2722     sqlite3DbFree(db, p->aScan);
  2726   2723   #endif
  2727   2724   }
  2728   2725   

Changes to src/where.c.

  2817   2817     SrcList *pTabList,              /* Table list this loop refers to */
  2818   2818     WhereLevel *pLevel,             /* Scan to write OP_Explain opcode for */
  2819   2819     int iLevel,                     /* Value for "level" column of output */
  2820   2820     int iFrom,                      /* Value for "from" column of output */
  2821   2821     u16 wctrlFlags                  /* Flags passed to sqlite3WhereBegin() */
  2822   2822   ){
  2823   2823     int ret = 0;
  2824         -#ifndef SQLITE_DEBUG
         2824  +#if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS)
  2825   2825     if( pParse->explain==2 )
  2826   2826   #endif
  2827   2827     {
  2828   2828       struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
  2829   2829       Vdbe *v = pParse->pVdbe;      /* VM being constructed */
  2830   2830       sqlite3 *db = pParse->db;     /* Database handle */
  2831   2831       int iId = pParse->iSelectId;  /* Select id (left-most output column) */