From: drh Date: Thu, 6 Nov 2014 04:42:20 +0000 (+0000) Subject: Add the SQLITE_SCANSTAT_SELECTID metric. Use it to improve the X-Git-Tag: version-3.8.8~178^2~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c6652b1efe79522c43acf10036fa9c6332efb270;p=thirdparty%2Fsqlite.git Add the SQLITE_SCANSTAT_SELECTID metric. Use it to improve the ".stmtscan on" output in the shell. FossilOrigin-Name: 64ad5761a841f71530d41565b9fbe9d19c2d6aff --- diff --git a/manifest b/manifest index 75d37178fb..25d04501fe 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -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 @@ -228,8 +228,8 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 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 @@ -291,8 +291,8 @@ F src/util.c 3b627daa45c7308c1e36e3dbaa3f9ce7e5c7fa73 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 @@ -1211,10 +1211,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 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 diff --git a/manifest.uuid b/manifest.uuid index d125168b7d..13ff805ffa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f9684000665ae7ef6f89c3773612b8286b8f545a \ No newline at end of file +64ad5761a841f71530d41565b9fbe9d19c2d6aff \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 4dd0ffa1a1..b6ae6e15a6 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1195,12 +1195,14 @@ static void display_scanstats( ){ #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; @@ -1208,13 +1210,23 @@ static void display_scanstats( 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, diff --git a/src/sqlite.h.in b/src/sqlite.h.in index c309dc1c5b..00bf5e2d98 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -7447,8 +7447,8 @@ int sqlite3_vtab_on_conflict(sqlite3 *); ** 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]]
SQLITE_SCANSTAT_NAME
**
^The "const char *" variable pointed to by the T parameter will be set to @@ -7459,6 +7459,13 @@ int sqlite3_vtab_on_conflict(sqlite3 *); **
^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]]
SQLITE_SCANSTAT_SELECT
+**
^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. ** */ #define SQLITE_SCANSTAT_NLOOP 0 @@ -7466,6 +7473,7 @@ int sqlite3_vtab_on_conflict(sqlite3 *); #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 diff --git a/src/vdbeInt.h b/src/vdbeInt.h index a42ca3dffc..1a7297e946 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -302,6 +302,7 @@ struct ScanStatus { 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 */ }; diff --git a/src/vdbeapi.c b/src/vdbeapi.c index d907afee00..5744c28632 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1521,6 +1521,14 @@ int sqlite3_stmt_scanstatus( } break; } + case SQLITE_SCANSTAT_SELECTID: { + if( pScan->addrExplain ){ + *(int*)pOut = p->aOp[ pScan->addrExplain ].p1; + }else{ + *(int*)pOut = -1; + } + break; + } default: { return 1; }