diff --git a/manifest b/manifest index 984bdbb4fc..420fc4058d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sOP_SqlExec\sopcode\sand\suse\sit\sto\simplement\s"PRAGMA\sanalyze_as_needed",\ninvoking\sANALYZE\ssubcommands\sas\snecessary.\s\sThis\ssimplifies\sthe\simplementation. -D 2017-02-18T15:58:52.451 +C Updated\scomments.\s\sNo\scode\schanges. +D 2017-02-18T22:52:40.654 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -387,7 +387,7 @@ F src/parse.y 591704fce84f814d9a3642774c1f011d38f4149c F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c 1ed159f6fed5af7f5b095f55bdefcb0848956397 +F src/pragma.c 8a35509e8f60746fbdcde5312ddfd177c46c7e9c F src/pragma.h 065e184494f12e94111da1ab6984faa7b6142e68 F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c @@ -1557,7 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4229caec0b60a1617b9d5ff94b47271cbd7be1e0 -R 03be76497e56750b0101f816e3587990 +P d386015f5e7ecdd951d70db56b7bbd858be7ad90 +R bb5056af5425096e2e052e924ae83b2e U drh -Z 8d178351b984357dd4d18d50fe476798 +Z a573182d78be17d037798d5840f110fc diff --git a/manifest.uuid b/manifest.uuid index 323aca9202..d08504dc8d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d386015f5e7ecdd951d70db56b7bbd858be7ad90 \ No newline at end of file +e842ad391e62df273a5b1ed569d42ea46d03a99b \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 49d711ded7..3aa07e8d18 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1830,16 +1830,33 @@ void sqlite3Pragma( /* ** PRAGMA analyze_as_needed + ** PRAGMA schema.analyze_as_needed + ** + ** This pragma runs ANALYZE on any tables which would have benefitted + ** from having recent statistics at some point since the start of the + ** current connection. Only tables in "schema" are analyzed in the + ** second form. In the first form, all tables except TEMP tables are + ** checked. + ** + ** A table is analyzed only if both of the following are true: + ** + ** (1) The query planner used sqlite_stat1-style statistics for one or + ** more indexes of the table at some point during the lifetime of + ** the current connection. + ** + ** (2) One or more indexes of the table are currently unanalyzed OR + ** the number of rows in the table has increased by 25 times or more + ** since the last time ANALYZE was run. */ case PragTyp_ANALYZE_AS_NEEDED: { - int iDbLast; - int iTabCur; - HashElem *k; - Schema *pSchema; - Table *pTab; - Index *pIdx; - LogEst szThreshold; - char *zSubSql; + int iDbLast; /* Loop termination point for the schema loop */ + int iTabCur; /* Cursor for a table whose size needs checking */ + HashElem *k; /* Loop over tables of a schema */ + Schema *pSchema; /* The current schema */ + Table *pTab; /* A table in the schema */ + Index *pIdx; /* An index of the table */ + LogEst szThreshold; /* Size threshold above which reanalysis is needd */ + char *zSubSql; /* SQL statement for the OP_SqlExec opcode */ iTabCur = pParse->nTab++; for(iDbLast = zDb?iDb:db->nDb-1; iDb<=iDbLast; iDb++){ @@ -1848,11 +1865,17 @@ void sqlite3Pragma( pSchema = db->aDb[iDb].pSchema; for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ pTab = (Table*)sqliteHashData(k); + + /* If table pTab has not been used in a way that would benefit from + ** having analysis statistics during the current session, then skip it. + ** This also has the effect of skipping virtual tables and views */ if( (pTab->tabFlags & TF_StatsUsed)==0 ) continue; + + /* Reanalyze if the table is 25 times larger than the last analysis */ szThreshold = pTab->nRowLogEst + 46; assert( sqlite3LogEst(25)==46 ); for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ if( !pIdx->hasStat1 ){ - szThreshold = 0; + szThreshold = 0; /* Always analyze if any index lacks statistics */ break; } }