From: drh Date: Tue, 31 Mar 2020 20:57:06 +0000 (+0000) Subject: Add "PRAGMA analysis_limit=N;" to limit the number of rows visited by X-Git-Tag: version-3.32.0~49^2~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=49a76a8fe5272426fee553d10111e5cf0babd571;p=thirdparty%2Fsqlite.git Add "PRAGMA analysis_limit=N;" to limit the number of rows visited by ANALYZE when N is positive. Positive N also disables collecting stat4. FossilOrigin-Name: a279b151c1623807774daf4975175c62ea252eefb71f9820ced6773769b392c5 --- diff --git a/manifest b/manifest index d4b41459ae..b3aa1c4102 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\srecent\senhancements\sfrom\strunk. -D 2020-03-31T18:41:21.038 +C Add\s"PRAGMA\sanalysis_limit=N;"\sto\slimit\sthe\snumber\sof\srows\svisited\sby\nANALYZE\swhen\sN\sis\spositive.\s\sPositive\sN\salso\sdisables\scollecting\sstat4. +D 2020-03-31T20:57:06.787 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -466,7 +466,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c f48a4423c8f198d7f1ae4940f74b606707d05384ac79fb219be8e3323af2a2de -F src/analyze.c 3d90f56656f5c6e7f835659b46ccf517c156df5222be86b4ff279eb476e8e373 +F src/analyze.c 4b139fa045d17192ba11ee97e6123cc011efbae690ec302f5d1eb53fd52d5ded F src/attach.c ff2daea0fe62080192e3f262670e4f61f5a86c1e7bea9cec34e960fe79852aa1 F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c 5e617c087f1c2d6005c2ec694ce80d6e16bc68d906e1b1c556d7c7c2228b636b @@ -524,8 +524,8 @@ F src/parse.y c8eff38606f443d5ba245263fa7abc05e4116d95656e050c4b78e9bfbf931add F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a -F src/pragma.c aff7b91cb36e58cee67d5dfc1c3a4b3c02aed104ce3ea1d6082aad2d61b445d7 -F src/pragma.h 9473160d220416456b40f27323bb4b316d4e4e08ffbf8bf88c5f7045d49c38e5 +F src/pragma.c 85f763714b192cc26a236e3ec020a9155fe8da248af21eae86c0d1f0f49a0753 +F src/pragma.h 8168e588536bffd95319451f34e9a754dc37d205ebe433031a7813c5b286beae F src/prepare.c 8d4d6c8aa6afefc48027c54b41cdf134b4d6bc2fc4badbe483ad7fd9e1728a28 F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 @@ -536,7 +536,7 @@ F src/shell.c.in 7bb9005bf876c4e1210257a63fa49b556f4eddf59f94b6eb310fcb5096bec0e F src/sqlite.h.in cc7d0949ac32bb68ed97acdb3e7ae91cd413a24d32d6ff049ef8308d620a4367 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9c5269260409eb3275324ccace6a13a96f4ad330c708415f70ca6097901ff4ee -F src/sqliteInt.h b0165686885990e29622f56b2f95b93c12c6f84be4cf1ee60797d80a0dcd7f15 +F src/sqliteInt.h 7bab5c24cd05f8173e1a30917857f42d8e1fbb834e9ea9c02ca23b50383e209d F src/sqliteLimit.h 95cb8479ca459496d9c1c6a9f76b38aee12203a56ce1092fe13e50ae2454c032 F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1793,7 +1793,7 @@ F tool/mkmsvcmin.tcl 6ecab9fe22c2c8de4d82d4c46797bda3d2deac8e763885f5a38d0c44a89 F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21 F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa -F tool/mkpragmatab.tcl 62663c65d9191aada624a787e1ee3420f268a3c27999ad0ffb77a6918ddc1e52 +F tool/mkpragmatab.tcl d348a4bf71ac068bddf89326562071cbbd962273d88f9b5e5d622f3e73b78bdf F tool/mkshellc.tcl 70a9978e363b0f3280ca9ce1c46d72563ff479c1930a12a7375e3881b7325712 F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 @@ -1860,7 +1860,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 8f0a8c2aa45f7cf7339094d83893aeb046b010b5b97bb4dae99ac07a8ebf2fa6 a49f8ec552bede7da731e0571ccf49de1a30e7be3a5673150436c8b411ba6ffc -R f330422722a52c77c50a3e7d8a9da878 +P c705ce266ad25af71791035590875f0ea9f2c72826b3eda17f065d2bf091de92 +R 89edd918806457e430236657da896c8f U drh -Z 2ae26fc9e4b49bbb8102a35ce551a2aa +Z bd47b9db8446ad6b70c7b3bf3d82180a diff --git a/manifest.uuid b/manifest.uuid index c079a7d71d..788d4b8710 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c705ce266ad25af71791035590875f0ea9f2c72826b3eda17f065d2bf091de92 \ No newline at end of file +a279b151c1623807774daf4975175c62ea252eefb71f9820ced6773769b392c5 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 4414c50807..2cad81817b 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -282,6 +282,7 @@ struct StatAccum { sqlite3 *db; /* Database connection, for malloc() */ tRowcnt nEst; /* Estimated number of rows */ tRowcnt nRow; /* Number of rows visited so far */ + int nLimit; /* Analysis row-scan limit */ int nCol; /* Number of columns in index + pk/rowid */ int nKeyCol; /* Number of index columns w/o the pk/rowid */ u8 nSkipAhead; /* Number of times of skip-ahead */ @@ -375,11 +376,12 @@ static void statAccumDestructor(void *pOld){ } /* -** Implementation of the stat_init(N,K,C) SQL function. The three parameters +** Implementation of the stat_init(N,K,C,L) SQL function. The four parameters ** are: ** N: The number of columns in the index including the rowid/pk (note 1) ** K: The number of columns in the index excluding the rowid/pk. ** C: Estimated number of rows in the index +** L: A limit on the number of rows to scan, or 0 for no-limit ** ** Note 1: In the special case of the covering index that implements a ** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the @@ -441,6 +443,11 @@ static void statInit( p->db = db; p->nEst = sqlite3_value_int64(argv[2]); p->nRow = 0; + p->nLimit = sqlite3_value_int64(argv[3]); +#ifdef SQLITE_ENABLE_STAT4 + /* Disable STAT4 statistics gathering if there is a analysis_limit set */ + if( p->nLimit>0 ) p->mxSample = 0; +#endif p->nCol = nCol; p->nKeyCol = nKeyCol; p->nSkipAhead = 0; @@ -677,15 +684,6 @@ static void samplePushPrevious(StatAccum *p, int iChng){ } #endif /* SQLITE_ENABLE_STAT4 */ -/* -** A limit on the number of rows of an index that will be examined -** by ANALYZE before it starts going with approximations. Zero means -** "no limit". -*/ -#ifndef SQLITE_ANALYZE_LIMIT -# define SQLITE_ANALYZE_LIMIT 0 -#endif - /* ** Implementation of the stat_push SQL function: stat_push(P,C,R) ** Arguments: @@ -774,14 +772,10 @@ static void statPush( } }else #endif -#if SQLITE_ANALYZE_LIMIT - if( p->nRow>SQLITE_ANALYZE_LIMIT*(p->nSkipAhead+1) ){ + if( p->nLimit && p->nRow>p->nLimit*(p->nSkipAhead+1) ){ p->nSkipAhead++; sqlite3_result_int(context, p->current.anDLt[0]>0); } -#else - {} -#endif } static const FuncDef statPushFuncdef = { @@ -987,6 +981,7 @@ static void analyzeOneTable( int regChng = iMem++; /* Index of changed index field */ int regRowid = iMem++; /* Rowid argument passed to stat_push() */ int regTemp = iMem++; /* Temporary use register */ + int regTemp2 = iMem++; /* Second temporary use register */ int regTabname = iMem++; /* Register containing table name */ int regIdxname = iMem++; /* Register containing index name */ int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */ @@ -1131,7 +1126,9 @@ static void analyzeOneTable( VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regTemp, 1); } - sqlite3VdbeAddFunctionCall(pParse, 0, regStat+1, regStat, 3, + assert( regTemp2==regStat+4 ); + sqlite3VdbeAddOp2(v, OP_Integer, db->nAnalysisLimit, regTemp2); + sqlite3VdbeAddFunctionCall(pParse, 0, regStat+1, regStat, 4, &statInitFuncdef, 0); /* Implementation of the following: @@ -1230,16 +1227,20 @@ static void analyzeOneTable( #endif assert( regChng==(regStat+1) ); { - int j1, j2, j3; sqlite3VdbeAddFunctionCall(pParse, 1, regStat, regTemp, 2+IsStat4, &statPushFuncdef, 0); - j1 = sqlite3VdbeAddOp1(v, OP_IsNull, regTemp); - j2 = sqlite3VdbeAddOp1(v, OP_If, regTemp); - j3 = sqlite3VdbeAddOp4Int(v, OP_SeekGT, iIdxCur, 0, regPrev, 1); - sqlite3VdbeJumpHere(v, j1); - sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v); - sqlite3VdbeJumpHere(v, j2); - sqlite3VdbeJumpHere(v, j3); + if( db->nAnalysisLimit ){ + int j1, j2, j3; + j1 = sqlite3VdbeAddOp1(v, OP_IsNull, regTemp); VdbeCoverage(v); + j2 = sqlite3VdbeAddOp1(v, OP_If, regTemp); VdbeCoverage(v); + j3 = sqlite3VdbeAddOp4Int(v, OP_SeekGT, iIdxCur, 0, regPrev, 1); + sqlite3VdbeJumpHere(v, j1); + sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, j2); + sqlite3VdbeJumpHere(v, j3); + }else{ + sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v); + } } /* Add the entry to the stat1 table. */ diff --git a/src/pragma.c b/src/pragma.c index e2c625549e..7105f75a97 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -2176,6 +2176,25 @@ void sqlite3Pragma( break; } + /* + ** PRAGMA analysis_limit + ** PRAGMA analysis_limit = N + ** + ** Configure the maximum number of rows that ANALYZE will examine + ** in each index that it looks at. Return the new limit. + */ + case PragTyp_ANALYSIS_LIMIT: { + sqlite3_int64 N; + if( zRight + && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK + && N>=0 + ){ + db->nAnalysisLimit = (int)(N&0x7fffffff); + } + returnSingleInt(v, db->nAnalysisLimit); + break; + } + #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) /* ** Report the current state of file logs for all databases diff --git a/src/pragma.h b/src/pragma.h index 7046695a5b..0d7cae0e1d 100644 --- a/src/pragma.h +++ b/src/pragma.h @@ -6,49 +6,50 @@ /* The various pragma types */ #define PragTyp_ACTIVATE_EXTENSIONS 0 -#define PragTyp_HEADER_VALUE 1 -#define PragTyp_AUTO_VACUUM 2 -#define PragTyp_FLAG 3 -#define PragTyp_BUSY_TIMEOUT 4 -#define PragTyp_CACHE_SIZE 5 -#define PragTyp_CACHE_SPILL 6 -#define PragTyp_CASE_SENSITIVE_LIKE 7 -#define PragTyp_COLLATION_LIST 8 -#define PragTyp_COMPILE_OPTIONS 9 -#define PragTyp_DATA_STORE_DIRECTORY 10 -#define PragTyp_DATABASE_LIST 11 -#define PragTyp_DEFAULT_CACHE_SIZE 12 -#define PragTyp_ENCODING 13 -#define PragTyp_FOREIGN_KEY_CHECK 14 -#define PragTyp_FOREIGN_KEY_LIST 15 -#define PragTyp_FUNCTION_LIST 16 -#define PragTyp_HARD_HEAP_LIMIT 17 -#define PragTyp_INCREMENTAL_VACUUM 18 -#define PragTyp_INDEX_INFO 19 -#define PragTyp_INDEX_LIST 20 -#define PragTyp_INTEGRITY_CHECK 21 -#define PragTyp_JOURNAL_MODE 22 -#define PragTyp_JOURNAL_SIZE_LIMIT 23 -#define PragTyp_LOCK_PROXY_FILE 24 -#define PragTyp_LOCKING_MODE 25 -#define PragTyp_PAGE_COUNT 26 -#define PragTyp_MMAP_SIZE 27 -#define PragTyp_MODULE_LIST 28 -#define PragTyp_OPTIMIZE 29 -#define PragTyp_PAGE_SIZE 30 -#define PragTyp_PRAGMA_LIST 31 -#define PragTyp_SECURE_DELETE 32 -#define PragTyp_SHRINK_MEMORY 33 -#define PragTyp_SOFT_HEAP_LIMIT 34 -#define PragTyp_SYNCHRONOUS 35 -#define PragTyp_TABLE_INFO 36 -#define PragTyp_TEMP_STORE 37 -#define PragTyp_TEMP_STORE_DIRECTORY 38 -#define PragTyp_THREADS 39 -#define PragTyp_WAL_AUTOCHECKPOINT 40 -#define PragTyp_WAL_CHECKPOINT 41 -#define PragTyp_LOCK_STATUS 42 -#define PragTyp_STATS 43 +#define PragTyp_ANALYSIS_LIMIT 1 +#define PragTyp_HEADER_VALUE 2 +#define PragTyp_AUTO_VACUUM 3 +#define PragTyp_FLAG 4 +#define PragTyp_BUSY_TIMEOUT 5 +#define PragTyp_CACHE_SIZE 6 +#define PragTyp_CACHE_SPILL 7 +#define PragTyp_CASE_SENSITIVE_LIKE 8 +#define PragTyp_COLLATION_LIST 9 +#define PragTyp_COMPILE_OPTIONS 10 +#define PragTyp_DATA_STORE_DIRECTORY 11 +#define PragTyp_DATABASE_LIST 12 +#define PragTyp_DEFAULT_CACHE_SIZE 13 +#define PragTyp_ENCODING 14 +#define PragTyp_FOREIGN_KEY_CHECK 15 +#define PragTyp_FOREIGN_KEY_LIST 16 +#define PragTyp_FUNCTION_LIST 17 +#define PragTyp_HARD_HEAP_LIMIT 18 +#define PragTyp_INCREMENTAL_VACUUM 19 +#define PragTyp_INDEX_INFO 20 +#define PragTyp_INDEX_LIST 21 +#define PragTyp_INTEGRITY_CHECK 22 +#define PragTyp_JOURNAL_MODE 23 +#define PragTyp_JOURNAL_SIZE_LIMIT 24 +#define PragTyp_LOCK_PROXY_FILE 25 +#define PragTyp_LOCKING_MODE 26 +#define PragTyp_PAGE_COUNT 27 +#define PragTyp_MMAP_SIZE 28 +#define PragTyp_MODULE_LIST 29 +#define PragTyp_OPTIMIZE 30 +#define PragTyp_PAGE_SIZE 31 +#define PragTyp_PRAGMA_LIST 32 +#define PragTyp_SECURE_DELETE 33 +#define PragTyp_SHRINK_MEMORY 34 +#define PragTyp_SOFT_HEAP_LIMIT 35 +#define PragTyp_SYNCHRONOUS 36 +#define PragTyp_TABLE_INFO 37 +#define PragTyp_TEMP_STORE 38 +#define PragTyp_TEMP_STORE_DIRECTORY 39 +#define PragTyp_THREADS 40 +#define PragTyp_WAL_AUTOCHECKPOINT 41 +#define PragTyp_WAL_CHECKPOINT 42 +#define PragTyp_LOCK_STATUS 43 +#define PragTyp_STATS 44 /* Property flags associated with various pragma. */ #define PragFlg_NeedSchema 0x01 /* Force schema load before running */ @@ -139,6 +140,11 @@ static const PragmaName aPragmaName[] = { /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif + {/* zName: */ "analysis_limit", + /* ePragTyp: */ PragTyp_ANALYSIS_LIMIT, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) {/* zName: */ "application_id", /* ePragTyp: */ PragTyp_HEADER_VALUE, @@ -639,4 +645,4 @@ static const PragmaName aPragmaName[] = { /* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError }, #endif }; -/* Number of pragmas: 66 on by default, 76 total. */ +/* Number of pragmas: 67 on by default, 77 total. */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index d08c7ce1e7..464ab91175 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1539,6 +1539,7 @@ struct sqlite3 { BusyHandler busyHandler; /* Busy callback */ Db aDbStatic[2]; /* Static space for the 2 default backends */ Savepoint *pSavepoint; /* List of active savepoints */ + int nAnalysisLimit; /* Number of index rows to ANALYZE */ int busyTimeout; /* Busy handler timeout, in msec */ int nSavepoint; /* Number of non-transaction savepoints */ int nStatement; /* Number of nested statement-transactions */ diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl index 7c8ffd3530..c33f20fd98 100644 --- a/tool/mkpragmatab.tcl +++ b/tool/mkpragmatab.tcl @@ -382,6 +382,9 @@ set pragma_def { NAME: threads FLAG: Result0 + NAME: analysis_limit + FLAG: Result0 + NAME: optimize FLAG: Result1 NeedSchema