-C Change\sthe\sSQLITE_SCANSTAT_EST\sparameter\sso\sthat\sit\sreturns\sa\sdouble\sfor\nthe\sestimated\snumber\sof\soutput\srows\sper\sloop,\srather\sthan\sa\s64-bit\sinteger.\nRevise\sthe\soutput\sformat\sfor\sthe\s".scanstats\son"\sin\sthe\sshell\sto\smake\suse\nof\sthis\snew\scapability.
-D 2014-11-06T03:55:10.745
+C Add\sthe\sSQLITE_SCANSTAT_SELECTID\smetric.\s\sUse\sit\sto\simprove\sthe\n".stmtscan\son"\soutput\sin\sthe\sshell.
+D 2014-11-06T04:42:20.310
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/resolve.c 4965007d6497b6a4d7a6d98751cc39712885f952
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
F src/select.c 428165951748151e87a15295b7357221433e311b
-F src/shell.c 908ff96ef1551b28b940aaf4c886ba2681057209
-F src/sqlite.h.in e13a7b64efa8d6a591577e6a5281fb22783c0133
+F src/shell.c 74768f90bd0f8880937d52e2eb756655dba0015a
+F src/sqlite.h.in 087d30a4c7ec7ae19bcaa03a9db9d6ee7a73b0b3
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
F src/sqliteInt.h 8f67ca79e957b8ece7453b8e320b6a996e1b4761
F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a
F src/vdbe.c 3fd4ebd3e87b63175bfd2be747608bae1670b4df
F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3
-F src/vdbeInt.h c32c1de25e3821a5b53d73abdb23ccc644ec5b63
-F src/vdbeapi.c 6a126fd8ed297ff0542bfbf7891b92977b5ed653
+F src/vdbeInt.h 9bb69ff2447c34b6ccc58b34ec35b615f86ead78
+F src/vdbeapi.c 07acb615d1e4170e71fc1b0d087f3c53a1ad8e83
F src/vdbeaux.c 9b0a251b6dfab349dd6c6efb40062eb7386b26f5
F src/vdbeblob.c 8b5442ff0954c44b45cbabbe2e94091a2e16fdef
F src/vdbemem.c 31d8eabb0cd78bfeab4e5124c7363c3e9e54db9f
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 272fddc14cc322655eeba670bc0f9fc30e5a804c
-R c0f850c2227a7a137fbc73d5c1c5136e
-T *branch * scanstatus
-T *sym-scanstatus *
-T -sym-trunk *
+P f9684000665ae7ef6f89c3773612b8286b8f545a
+R 34f47ade33b56f41a439ae08635a112b
U drh
-Z f39cd1607e4aacbb491c044bd0bb317e
+Z 216d325be8d3eddf6fd433a7ff464585
-f9684000665ae7ef6f89c3773612b8286b8f545a
\ No newline at end of file
+64ad5761a841f71530d41565b9fbe9d19c2d6aff
\ No newline at end of file
){
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
int i;
- double rEstLoop = 1.0;
+ double *arEstLoop = 0;
+ int nEstLoop = 0;
fprintf(pArg->out, "-------- scanstats --------\n");
for(i=0; 1; i++){
sqlite3_stmt *p = pArg->pStmt;
sqlite3_int64 nLoop, nVisit;
- double rEst;
+ double rEst, rLoop;
+ int iSid;
const char *zExplain;
if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
break;
sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
-
+ sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
+ if( iSid>=nEstLoop ){
+ arEstLoop = sqlite3_realloc(arEstLoop, sizeof(arEstLoop[0])*(iSid+1) );
+ while( nEstLoop<=iSid ) arEstLoop[nEstLoop++] = 1.0;
+ }
+ if( iSid>=0 ){
+ arEstLoop[iSid] *= rEst;
+ rLoop = arEstLoop[iSid];
+ }else{
+ rLoop = rEst;
+ }
fprintf(pArg->out, "Loop %2d: \"%s\"\n", i, zExplain);
- rEstLoop *= rEst;
fprintf(pArg->out, " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
- nLoop, nVisit, (sqlite3_int64)rEstLoop, rEst
+ nLoop, nVisit, (sqlite3_int64)rLoop, rEst
);
}
+ sqlite3_free(arEstLoop);
#else
fprintf(pArg->out, "-------- scanstats --------\n");
fprintf(pArg->out,
** query planner's estimate for the average number of rows output from each
** iteration of the X-th loop. If the query planner's estimates was accurate,
** then this value will approximate the quotient NVISIT/NLOOP and the
-** product of this value for the first N-1 loops will approximate
-** the NLOOP value for the N-th loop.
+** product of this value for all prior loops with the same SELECTID will
+** be the NLOOP value for the current loop.
**
** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt>
** <dd>^The "const char *" variable pointed to by the T parameter will be set to
** <dd>^The "const char *" variable pointed to by the T parameter will be set to
** a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] description
** for the X-th loop.
+**
+** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt>
+** <dd>^The "int" variable pointed to by the T parameter will be set to the
+** "select-id" for the X-th loop. The select-id identifies which query or
+** subquery the loop is part of. The main query has a select-id of zero.
+** The select-id is the same value as is output in the first column
+** of an [EXPLAIN QUERY PLAN] query.
** </dl>
*/
#define SQLITE_SCANSTAT_NLOOP 0
#define SQLITE_SCANSTAT_EST 2
#define SQLITE_SCANSTAT_NAME 3
#define SQLITE_SCANSTAT_EXPLAIN 4
+#define SQLITE_SCANSTAT_SELECTID 5
/*
** CAPI3REF: Prepared Statement Scan Status
int addrExplain; /* OP_Explain for loop */
int addrLoop; /* Address of "loops" counter */
int addrVisit; /* Address of "rows visited" counter */
+ int iSelectID; /* The "Select-ID" for this loop */
LogEst nEst; /* Estimated output rows per loop */
char *zName; /* Name of table or index */
};
}
break;
}
+ case SQLITE_SCANSTAT_SELECTID: {
+ if( pScan->addrExplain ){
+ *(int*)pOut = p->aOp[ pScan->addrExplain ].p1;
+ }else{
+ *(int*)pOut = -1;
+ }
+ break;
+ }
default: {
return 1;
}