]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add "PRAGMA analysis_limit=N;" to limit the number of rows visited by
authordrh <drh@noemail.net>
Tue, 31 Mar 2020 20:57:06 +0000 (20:57 +0000)
committerdrh <drh@noemail.net>
Tue, 31 Mar 2020 20:57:06 +0000 (20:57 +0000)
ANALYZE when N is positive.  Positive N also disables collecting stat4.

FossilOrigin-Name: a279b151c1623807774daf4975175c62ea252eefb71f9820ced6773769b392c5

manifest
manifest.uuid
src/analyze.c
src/pragma.c
src/pragma.h
src/sqliteInt.h
tool/mkpragmatab.tcl

index d4b41459ae98bf3423e5b45ef50e5e34c87f92ca..b3aa1c4102282b150755aee56c5bcba178e07934 100644 (file)
--- 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
index c079a7d71dbcb33dcee413e5e55086054bfdbde0..788d4b8710412da2a604b125ca0da7e7f3f4d5b2 100644 (file)
@@ -1 +1 @@
-c705ce266ad25af71791035590875f0ea9f2c72826b3eda17f065d2bf091de92
\ No newline at end of file
+a279b151c1623807774daf4975175c62ea252eefb71f9820ced6773769b392c5
\ No newline at end of file
index 4414c50807a38158e7ecdd99a4a7c31b3e8834cb..2cad81817bd84281b5eac7550629bb84651440ab 100644 (file)
@@ -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. */
index e2c625549ef7160e5627f92eacdcc8a45863f285..7105f75a9748832e0950d9332ee035ef12ac3328 100644 (file)
@@ -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
index 7046695a5b4d84a49ebe13321d35cd89f764a4bc..0d7cae0e1dd240d55e4283e1ea02eb9f5d22f678 100644 (file)
@@ -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. */
index d08c7ce1e740b706212e49a5b4845dac2776f805..464ab911758c78395133e7b82be932924cba0fad 100644 (file)
@@ -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  */
index 7c8ffd35308214fcd64028594c3474ffc124a962..c33f20fd98c2b82cc5305b6bb34963665026485f 100644 (file)
@@ -382,6 +382,9 @@ set pragma_def {
   NAME: threads
   FLAG: Result0
 
+  NAME: analysis_limit
+  FLAG: Result0
+
   NAME: optimize
   FLAG: Result1 NeedSchema