]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Enhance speedtest1 with a new testset that calls sqlite3_open() and uses the
authordrh <>
Mon, 10 Feb 2025 16:13:56 +0000 (16:13 +0000)
committerdrh <>
Mon, 10 Feb 2025 16:13:56 +0000 (16:13 +0000)
connection many times.

FossilOrigin-Name: ce307addb0c7cf72e4cca066521df6e15d1220bce303a3796a794a2ae5fa95b3

manifest
manifest.uuid
test/speedtest1.c

index 356f13117071edd33db1449c0912ae2f92822358..8a2dd3ba4328736a0d13dd00e58bf09122908d41 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sjimsh.exe\sand\sjimsh0.exe\sto\sthe\sclean\srules\sin\sMakefile.msc\sso\sthat\sstale\sbuilds\sof\sthose\sfiles\sfrom\smsys2\sand\sfriends\sdo\snot\scause\smysterious\sbuild\serrors.
-D 2025-02-10T15:58:22.800
+C Enhance\sspeedtest1\swith\sa\snew\stestset\sthat\scalls\ssqlite3_open()\sand\suses\sthe\nconnection\smany\stimes.
+D 2025-02-10T16:13:56.580
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d
@@ -1681,7 +1681,7 @@ F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
 F test/speed4p.test 377a0c48e5a92e0b11c1c5ebb1bc9d83a7312c922bc0cb05970ef5d6a96d1f0c
 F test/speedtest.md ee958457ae1b729d9715ae33c0320600000bf1d9ddea1a88dcf79f56729d6fad
 F test/speedtest.tcl 185f80f8db275852746e8150137b31ba4aaa1c9a1ecb1e35a3b66cd3f31783b9 x
-F test/speedtest1.c ef340d391366afc875d11fc59332601c470154352b0db836b2cba813999a8fb4
+F test/speedtest1.c abcce434642f8f1e1be530d25d8e7d7862360236d7a8e4f626521bc3263bd38c
 F test/spellfix.test 951a6405d49d1a23d6b78027d3877b4a33eeb8221dcab5704b499755bb4f552e
 F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3
 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33
@@ -2209,8 +2209,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P f28e52cbf9e80cb5a1cde7cba099e2c2b6787a77263796e4f9febf3f30bc99dc
-R 9884f4a919e7e313dc0ab42868810e5c
-U stephan
-Z 6aa92bc3b567c51b695c0a3eafdd20c2
+P 44b4e4db321815c6fc0327ed7b97df868833654411e882b70f54ad3f6d212987
+R 6770e3052628a73d65a1abe270e15306
+U drh
+Z b145be6a514a8b9ab22ab7f6982431ae
 # Remove this line to create a well-formed Fossil manifest.
index 024fc6f4cfa793c266ba71b226e35040a6f7fc59..2351f8f43892450891dc508a58b0baf9cdded128 100644 (file)
@@ -1 +1 @@
-44b4e4db321815c6fc0327ed7b97df868833654411e882b70f54ad3f6d212987
+ce307addb0c7cf72e4cca066521df6e15d1220bce303a3796a794a2ae5fa95b3
index c6d5fd4a1099cd0ab41654335dc64f0b440cc935..a03bdbb73b9a22b28dccf22f0e89dcdcb5920f3c 100644 (file)
@@ -65,8 +65,8 @@ static const char zHelp[] =
   "  --stmtscanstatus    Activate SQLITE_DBCONFIG_STMT_SCANSTATUS\n"
   "  --temp N            N from 0 to 9.  0: no temp table. 9: all temp tables\n"
   "  --testset T         Run test-set T (main, cte, rtree, orm, fp, json,\n"
-  "                      star, debug).  Can be a comma-separated list of\n"
-  "                      values, with /SCALE suffixes or macro \"mix1\"\n"
+  "                      star, app, debug).  Can be a comma-separated list\n"
+  "                      of values, with /SCALE suffixes or macro \"mix1\"\n"
   "  --trace             Turn on SQL tracing\n"
   "  --threads N         Use up to N threads for sorting\n"
   "  --utf16be           Set text encoding to UTF-16BE\n"
@@ -112,6 +112,8 @@ struct HashContext {
 /* All global state is held in this structure */
 static struct Global {
   sqlite3 *db;               /* The open database connection */
+  const char *zDbName;       /* Name of the database file */
+  const char *zVfs;          /* --vfs NAME */
   sqlite3_stmt *pStmt;       /* Current SQL statement */
   sqlite3_int64 iStart;      /* Start-time for the current test */
   sqlite3_int64 iTotal;      /* Total time */
@@ -1565,6 +1567,453 @@ void testset_star(void){
   speedtest1_end_test();
 }
 
+/*
+** Tests that simulate an application opening and closing an SQLite database
+** frequently.  Fossil is used as the model.  The focus here is on rapidly
+** parsing the database schema and rapidly generating prepared statements,
+** in other words, rapid start-up of Fossil-like applications.
+**
+** The same database has no data, so the performance of sqlite3_step() is
+** not significant to this testset.
+*/
+static void testset_app(void){
+  int i, n;
+  speedtest1_begin_test(100, "Generate a Fossil-like database schema");
+  speedtest1_exec(
+    "BEGIN;"
+    "CREATE TABLE blob(\n"
+    "  rid INTEGER PRIMARY KEY,\n"
+    "  rcvid INTEGER,\n"
+    "  size INTEGER,\n"
+    "  uuid TEXT UNIQUE NOT NULL,\n"
+    "  content BLOB,\n"
+    "  CHECK( length(uuid)>=40 AND rid>0 )\n"
+    ");\n"
+    "CREATE TABLE delta(\n"
+    "  rid INTEGER PRIMARY KEY,\n"
+    "  srcid INTEGER NOT NULL REFERENCES blob\n"
+    ");\n"
+    "CREATE TABLE rcvfrom(\n"
+    "  rcvid INTEGER PRIMARY KEY,\n"
+    "  uid INTEGER REFERENCES user,\n"
+    "  mtime DATETIME,\n"
+    "  nonce TEXT UNIQUE,\n"
+    "  ipaddr TEXT\n"
+    ");\n"
+    "CREATE TABLE private(rid INTEGER PRIMARY KEY);\n"
+    "CREATE TABLE accesslog(\n"
+    "  uname TEXT,\n"
+    "  ipaddr TEXT,\n"
+    "  success BOOLEAN,\n"
+    "  mtime TIMESTAMP\n"
+    ");\n"
+    "CREATE TABLE user(\n"
+    "  uid INTEGER PRIMARY KEY,\n"
+    "  login TEXT UNIQUE,\n"
+    "  pw TEXT,\n"
+    "  cap TEXT,\n"
+    "  cookie TEXT,\n"
+    "  ipaddr TEXT,\n"
+    "  cexpire DATETIME,\n"
+    "  info TEXT,\n"
+    "  mtime DATE,\n"
+    "  photo BLOB\n"
+    ", jx TEXT DEFAULT '{}');\n"
+    "CREATE TABLE reportfmt(\n"
+    "   rn INTEGER PRIMARY KEY,\n"
+    "   owner TEXT,\n"
+    "   title TEXT UNIQUE,\n"
+    "   mtime INTEGER,\n"
+    "   cols TEXT,\n"
+    "   sqlcode TEXT\n"
+    ", jx TEXT DEFAULT '{}');\n"
+    "CREATE TABLE config(\n"
+    "  name TEXT PRIMARY KEY NOT NULL,\n"
+    "  value CLOB, mtime INTEGER,\n"
+    "  CHECK( typeof(name)='text' AND length(name)>=1 )\n"
+    ") WITHOUT ROWID;\n"
+    "CREATE TABLE shun(uuid PRIMARY KEY, mtime INTEGER, scom TEXT)\n"
+    "  WITHOUT ROWID;\n"
+    "CREATE TABLE concealed(\n"
+    "  hash TEXT PRIMARY KEY,\n"
+    "  content TEXT\n"
+    ", mtime INTEGER) WITHOUT ROWID;\n"
+    "CREATE TABLE admin_log(\n"
+    " id INTEGER PRIMARY KEY,\n"
+    " time INTEGER, -- Seconds since 1970\n"
+    " page TEXT,    -- path of page\n"
+    " who TEXT,     -- User who made the change\n"
+    "  what TEXT     -- What changed\n"
+    ");\n"
+    "CREATE TABLE unversioned(\n"
+    "  name TEXT PRIMARY KEY,\n"
+    "  rcvid INTEGER,\n"
+    "  mtime DATETIME,\n"
+    "  hash TEXT,\n"
+    "  sz INTEGER,\n"
+    "  encoding INT,\n"
+    "  content BLOB\n"
+    ") WITHOUT ROWID;\n"
+    "CREATE TABLE subscriber(\n"
+    "  subscriberId INTEGER PRIMARY KEY,\n"
+    "  subscriberCode BLOB DEFAULT (randomblob(32)) UNIQUE,\n"
+    "  semail TEXT UNIQUE COLLATE nocase,\n"
+    "  suname TEXT,\n"
+    "  sverified BOOLEAN DEFAULT true,\n"
+    "  sdonotcall BOOLEAN,\n"
+    "  sdigest BOOLEAN,\n"
+    "  ssub TEXT,\n"
+    "  sctime INTDATE,\n"
+    "  mtime INTDATE,\n"
+    "  smip TEXT\n"
+    ", lastContact INT);\n"
+    "CREATE TABLE pending_alert(\n"
+    "  eventid TEXT PRIMARY KEY,\n"
+    "  sentSep BOOLEAN DEFAULT false,\n"
+    "  sentDigest BOOLEAN DEFAULT false\n"
+    ", sentMod BOOLEAN DEFAULT false) WITHOUT ROWID;\n"
+    "CREATE TABLE filename(\n"
+    "  fnid INTEGER PRIMARY KEY,\n"
+    "  name TEXT UNIQUE\n"
+    ") STRICT;\n"
+    "CREATE TABLE mlink(\n"
+    "  mid INTEGER,\n"
+    "  fid INTEGER,\n"
+    "  pmid INTEGER,\n"
+    "  pid INTEGER,\n"
+    "  fnid INTEGER REFERENCES filename,\n"
+    "  pfnid INTEGER,\n"
+    "  mperm INTEGER,\n"
+    "  isaux INT DEFAULT 0\n"
+    ") STRICT;\n"
+    "CREATE TABLE plink(\n"
+    "  pid INTEGER REFERENCES blob,\n"
+    "  cid INTEGER REFERENCES blob,\n"
+    "  isprim INT,\n"
+    "  mtime REAL,\n"
+    "  baseid INTEGER REFERENCES blob,\n"
+    "  UNIQUE(pid, cid)\n"
+    ") STRICT;\n"
+    "CREATE TABLE leaf(rid INTEGER PRIMARY KEY);\n"
+    "CREATE TABLE event(\n"
+    "  type TEXT,\n"
+    "  mtime REAL,\n"
+    "  objid INTEGER PRIMARY KEY,\n"
+    "  tagid INTEGER,\n"
+    "  uid INTEGER REFERENCES user,\n"
+    "  bgcolor TEXT,\n"
+    "  euser TEXT,\n"
+    "  user TEXT,\n"
+    "  ecomment TEXT,\n"
+    "  comment TEXT,\n"
+    "  brief TEXT,\n"
+    "  omtime REAL\n"
+    ") STRICT;\n"
+    "CREATE TABLE phantom(\n"
+    "  rid INTEGER PRIMARY KEY\n"
+    ");\n"
+    "CREATE TABLE orphan(\n"
+    "  rid INTEGER PRIMARY KEY,\n"
+    "  baseline INTEGER\n"
+    ") STRICT;\n"
+    "CREATE TABLE unclustered(\n"
+    "  rid INTEGER PRIMARY KEY\n"
+    ");\n"
+    "CREATE TABLE unsent(\n"
+    "  rid INTEGER PRIMARY KEY\n"
+    ");\n"
+    "CREATE TABLE tag(\n"
+    "  tagid INTEGER PRIMARY KEY,\n"
+    "  tagname TEXT UNIQUE\n"
+    ") STRICT;\n"
+    "CREATE TABLE tagxref(\n"
+    "  tagid INTEGER REFERENCES tag,\n"
+    "  tagtype INTEGER,\n"
+    "  srcid INTEGER REFERENCES blob,\n"
+    "  origid INTEGER REFERENCES blob,\n"
+    "  value TEXT,\n"
+    "  mtime REAL,\n"
+    "  rid INTEGER REFERENCES blob,\n"
+    "  UNIQUE(rid, tagid)\n"
+    ") STRICT;\n"
+    "CREATE TABLE backlink(\n"
+    "  target TEXT,\n"
+    "  srctype INT,\n"
+    "  srcid INT,\n"
+    "  mtime REAL,\n"
+    "  UNIQUE(target, srctype, srcid)\n"
+    ") STRICT;\n"
+    "CREATE TABLE attachment(\n"
+    "  attachid INTEGER PRIMARY KEY,\n"
+    "  isLatest INT DEFAULT 0,\n"
+    "  mtime REAL,\n"
+    "  src TEXT,\n"
+    "  target TEXT,\n"
+    "  filename TEXT,\n"
+    "  comment TEXT,\n"
+    "  user TEXT\n"
+    ") STRICT;\n"
+    "CREATE TABLE cherrypick(\n"
+    "  parentid INT,\n"
+    "  childid INT,\n"
+    "  isExclude INT DEFAULT false,\n"
+    "  PRIMARY KEY(parentid, childid)\n"
+    ") WITHOUT ROWID, STRICT;\n"
+    "CREATE TABLE vcache(\n"
+    "  vid INTEGER,         -- check-in ID\n"
+    "  fname TEXT,          -- filename\n"
+    "  rid INTEGER,         -- artifact ID\n"
+    "  PRIMARY KEY(vid,fname)\n"
+    ") WITHOUT ROWID;\n"
+    "CREATE TABLE synclog(\n"
+    "  sfrom TEXT,\n"
+    "  sto TEXT,\n"
+    "  stime INT NOT NULL,\n"
+    "  stype TEXT,\n"
+    "  PRIMARY KEY(sfrom,sto)\n"
+    ") WITHOUT ROWID;\n"
+    "CREATE TABLE chat(\n"
+    "  msgid INTEGER PRIMARY KEY AUTOINCREMENT,\n"
+    "  mtime JULIANDAY,\n"
+    "  lmtime TEXT,\n"
+    "  xfrom TEXT,\n"
+    "  xmsg  TEXT,\n"
+    "  fname TEXT,\n"
+    "  fmime TEXT,\n"
+    "  mdel INT,\n"
+    "  file  BLOB\n"
+    ");\n"
+    "CREATE TABLE ftsdocs(\n"
+    "  rowid INTEGER PRIMARY KEY,\n"
+    "  type CHAR(1),\n"
+    "  rid INTEGER,\n"
+    "  name TEXT,\n"
+    "  idxed BOOLEAN,\n"
+    "  label TEXT,\n"
+    "  url TEXT,\n"
+    "  mtime DATE,\n"
+    "  bx TEXT,\n"
+    "  UNIQUE(type,rid)\n"
+    ");\n"
+    "CREATE TABLE ticket(\n"
+    "  -- Do not change any column that begins with tkt_\n"
+    "  tkt_id INTEGER PRIMARY KEY,\n"
+    "  tkt_uuid TEXT UNIQUE,\n"
+    "  tkt_mtime DATE,\n"
+    "  tkt_ctime DATE,\n"
+    "  -- Add as many fields as required below this line\n"
+    "  type TEXT,\n"
+    "  status TEXT,\n"
+    "  subsystem TEXT,\n"
+    "  priority TEXT,\n"
+    "  severity TEXT,\n"
+    "  foundin TEXT,\n"
+    "  private_contact TEXT,\n"
+    "  resolution TEXT,\n"
+    "  title TEXT,\n"
+    "  comment TEXT\n"
+    ");\n"
+    "CREATE TABLE ticketchng(\n"
+    "  -- Do not change any column that begins with tkt_\n"
+    "  tkt_id INTEGER REFERENCES ticket,\n"
+    "  tkt_rid INTEGER REFERENCES blob,\n"
+    "  tkt_mtime DATE,\n"
+    "  tkt_user TEXT,\n"
+    "  -- Add as many fields as required below this line\n"
+    "  login TEXT,\n"
+    "  username TEXT,\n"
+    "  mimetype TEXT,\n"
+    "  icomment TEXT\n"
+    ");\n"
+    "CREATE TABLE forumpost(\n"
+    "  fpid INTEGER PRIMARY KEY,\n"
+    "  froot INT,\n"
+    "  fprev INT,\n"
+    "  firt INT,\n"
+    "  fmtime REAL\n"
+    ");\n"
+    "CREATE INDEX delta_i1 ON delta(srcid);\n"
+    "CREATE INDEX blob_rcvid ON blob(rcvid);\n"
+    "CREATE INDEX subscriberUname\n"
+    "  ON subscriber(suname) WHERE suname IS NOT NULL;\n"
+    "CREATE INDEX mlink_i1 ON mlink(mid);\n"
+    "CREATE INDEX mlink_i2 ON mlink(fnid);\n"
+    "CREATE INDEX mlink_i3 ON mlink(fid);\n"
+    "CREATE INDEX mlink_i4 ON mlink(pid);\n"
+    "CREATE INDEX plink_i2 ON plink(cid,pid);\n"
+    "CREATE INDEX event_i1 ON event(mtime);\n"
+    "CREATE INDEX orphan_baseline ON orphan(baseline);\n"
+    "CREATE INDEX tagxref_i1 ON tagxref(tagid, mtime);\n"
+    "CREATE INDEX backlink_src ON backlink(srcid, srctype);\n"
+    "CREATE INDEX attachment_idx1 ON attachment(target, filename, mtime);\n"
+    "CREATE INDEX attachment_idx2 ON attachment(src);\n"
+    "CREATE INDEX cherrypick_cid ON cherrypick(childid);\n"
+    "CREATE INDEX ftsdocIdxed ON ftsdocs(type,rid,name) WHERE idxed==0;\n"
+    "CREATE INDEX ftsdocName ON ftsdocs(name) WHERE type='w';\n"
+    "CREATE INDEX ticketchng_idx1 ON ticketchng(tkt_id, tkt_mtime);\n"
+    "CREATE INDEX forumthread ON forumpost(froot,fmtime);\n"
+    "CREATE VIEW artifact(rid,rcvid,size,atype,srcid,hash,content) AS\n"
+    "  SELECT blob.rid,rcvid,size,1,srcid,uuid,content\n"
+    "    FROM blob LEFT JOIN delta ON (blob.rid=delta.rid);\n"
+    "CREATE VIEW ftscontent AS\n"
+    "  SELECT rowid, type, rid, name, idxed, label, url, mtime,\n"
+    "         title(type,rid,name) AS 'title', body(type,rid,name) AS 'body'\n"
+    "    FROM ftsdocs;\n"
+  );
+  if( sqlite3_compileoption_used("ENABLE_FTS5") ){
+    speedtest1_exec(
+      "CREATE VIRTUAL TABLE ftsidx\n"
+      "  USING fts5(content=\"ftscontent\", title, body);\n"
+      "CREATE VIRTUAL TABLE chatfts1 USING fts5(\n"
+      "  xmsg, content=chat, content_rowid=msgid,tokenize=porter);\n"
+    );
+  }else{
+    speedtest1_exec(
+      "CREATE TABLE ftsidx_data(id INTEGER PRIMARY KEY, block BLOB);\n"
+      "CREATE TABLE ftsidx_idx(segid, term, pgno, PRIMARY KEY(segid, term))\n"
+      "  WITHOUT ROWID;\n"
+      "CREATE TABLE ftsidx_docsize(id INTEGER PRIMARY KEY, sz BLOB);\n"
+      "CREATE TABLE ftsidx_config(k PRIMARY KEY, v) WITHOUT ROWID;\n"
+      "CREATE TABLE chatfts1_data(id INTEGER PRIMARY KEY, block BLOB);\n"
+      "CREATE TABLE chatfts1_idx(segid, term, pgno, PRIMARY KEY(segid, term))\n"
+      "  WITHOUT ROWID;\n"
+      "CREATE TABLE chatfts1_docsize(id INTEGER PRIMARY KEY, sz BLOB);\n"
+      "CREATE TABLE chatfts1_config(k PRIMARY KEY, v) WITHOUT ROWID;\n"
+    );
+  }
+  speedtest1_exec(
+    "ANALYZE sqlite_schema;\n"
+    "INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES\n"
+    "  ('ftsidx_config','ftsidx_config','1 1'),\n"
+    "  ('ftsidx_idx','ftsidx_idx','4215 401 1'),\n"
+    "  ('user','sqlite_autoindex_user_1','25 1'),\n"
+    "  ('phantom',NULL,'26'),\n"
+    "  ('reportfmt','sqlite_autoindex_reportfmt_1','9 1'),\n"
+    "  ('rcvfrom','sqlite_autoindex_rcvfrom_1','18445 401'),\n"
+    "  ('private',NULL,'99'),\n"
+    "  ('mlink','mlink_i4','116678 401'),\n"
+    "  ('mlink','mlink_i3','121212 2'),\n"
+    "  ('mlink','mlink_i2','106372 401'),\n"
+    "  ('mlink','mlink_i1','99298 5'),\n"
+    "  ('ftsidx_data',NULL,'3795'),\n"
+    "  ('leaf',NULL,'1559'),\n"
+    "  ('delta','delta_i1','66340 1'),\n"
+    "  ('unversioned','unversioned','3 1'),\n"
+    "  ('pending_alert','pending_alert','3 1'),\n"
+    "  ('cherrypick','cherrypick_cid','680 2'),\n"
+    "  ('cherrypick','cherrypick','628 1 1'),\n"
+    "  ('config','config','128 1'),\n"
+    "  ('ftsidx_docsize',NULL,'33848'),\n"
+    "  ('event','event_i1','36096 1'),\n"
+    "  ('plink','plink_i2','38236 1 1'),\n"
+    "  ('plink','sqlite_autoindex_plink_1','38357 1 1'),\n"
+    "  ('shun','shun','10 1'),\n"
+    "  ('concealed','concealed','110 1'),\n"
+    "  ('vcache','vcache','1888 401 1'),\n"
+    "  ('ftsdocs','ftsdocName','19 1'),\n"
+    "  ('ftsdocs','ftsdocIdxed','168 84 1 1'),\n"
+    "  ('ftsdocs','sqlite_autoindex_ftsdocs_1','37312 401 1'),\n"
+    "  ('subscriber','subscriberUname','5 1'),\n"
+    "  ('subscriber','sqlite_autoindex_subscriber_2','37 1'),\n"
+    "  ('subscriber','sqlite_autoindex_subscriber_1','37 1'),\n"
+    "  ('tag','sqlite_autoindex_tag_1','2990 1'),\n"
+    "  ('filename','sqlite_autoindex_filename_1','3168 1'),\n"
+    "  ('chat',NULL,'56124'),\n"
+    "  ('tagxref','tagxref_i1','40992 401 2'),\n"
+    "  ('tagxref','sqlite_autoindex_tagxref_1','79233 3 1'),\n"
+    "  ('attachment','attachment_idx2','11 1'),\n"
+    "  ('attachment','attachment_idx1','11 2 2 1'),\n"
+    "  ('blob','blob_rcvid','128240 201'),\n"
+    "  ('blob','sqlite_autoindex_blob_1','126480 1'),\n"
+    "  ('synclog','synclog','12 3 1'),\n"
+    "  ('backlink','backlink_src','2160 2 2'),\n"
+    "  ('backlink','sqlite_autoindex_backlink_1','2340 2 2 1'),\n"
+    "  ('accesslog',NULL,'38'),\n"
+    "  ('chatfts1_config','chatfts1_config','1 1'),\n"
+    "  ('chatfts1_idx','chatfts1_idx','688 230 1'),\n"
+    "  ('ticket','sqlite_autoindex_ticket_1','794 1'),\n"
+    "  ('ticketchng','ticketchng_idx1','2089 3 1'),\n"
+    "  ('forumpost','forumthread','4 4 1'),\n"
+    "  ('unclustered',NULL,'12');\n"
+    "COMMIT;"
+  );
+  speedtest1_end_test();
+
+  n = g.szTest*3;
+  speedtest1_begin_test(110, "Open and use the database %d times", n);
+  for(i=0; i<n; i++){
+    sqlite3 *dbMain = g.db;
+    sqlite3 *dbAux = 0;
+    if( g.zDbName && g.zDbName[0] ){
+      if( sqlite3_open_v2(g.zDbName, &dbAux, SQLITE_OPEN_READWRITE, g.zVfs) ){
+        fatal_error("Cannot open database file: %s\n", g.zDbName);
+      }
+      g.db = dbAux;
+    }
+    speedtest1_exec(
+      "SELECT name FROM pragma_table_list /*scan*/"
+      " WHERE schema='repository' AND type IN ('table','virtual')"
+      " AND name NOT IN ('admin_log', 'blob','delta','rcvfrom','user','alias',"
+                        "'config','shun','private','reportfmt',"
+                        "'concealed','accesslog','modreq',"
+                        "'purgeevent','purgeitem','unversioned',"
+                        "'subscriber','pending_alert','chat')"
+      " AND name NOT GLOB 'sqlite_*'"
+      " AND name NOT GLOB 'fx_*';"
+      "SELECT 1 FROM pragma_table_xinfo('ticket') WHERE name = 'mimetype';"
+    );
+    speedtest1_exec(
+      "SELECT"
+      " name,"
+      " value,"
+      " unixepoch()/86400-value,"
+      " date(value*86400,'unixepoch')"
+      " FROM config"
+      " WHERE name in ('email-renew-warning','email-renew-cutoff');"
+      "SELECT count(*) FROM pending_alert WHERE NOT sentDigest;"
+    );
+    speedtest1_exec(
+      "WITH priors(rid,who) AS ("
+      "  SELECT firt, coalesce(euser,user)"
+      "    FROM forumpost LEFT JOIN event ON fpid=objid"
+      "   WHERE fpid=12345"
+      "  UNION ALL"
+      "  SELECT firt, coalesce(euser,user)"
+      "    FROM priors, forumpost LEFT JOIN event ON fpid=objid"
+      "   WHERE fpid=rid"
+      ")"
+      "SELECT ','||group_concat(DISTINCT 'u'||who)||"
+             "','||group_concat(rid) FROM priors;"
+    );
+    speedtest1_exec(
+      "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY);\n"
+    );
+    speedtest1_exec(
+      "WITH RECURSIVE\n"
+      "  parent(pid,cid,isCP) AS (\n"
+      "    SELECT plink.pid, plink.cid, 0 AS xisCP FROM plink\n"
+      "    UNION ALL\n"
+      "    SELECT parentid, childid, 1 FROM cherrypick WHERE NOT isExclude\n"
+      "  ),\n"
+      "  ancestor(rid, mtime, isCP) AS (\n"
+      "    SELECT 123, mtime, 0 FROM event WHERE objid=$object\n"
+      "    UNION\n"
+      "    SELECT parent.pid, event.mtime, parent.isCP\n"
+      "      FROM ancestor, parent, event\n"
+      "     WHERE parent.cid=ancestor.rid\n"
+      "       AND event.objid=parent.pid\n"
+      "       AND NOT ancestor.isCP\n"
+      "       AND (event.mtime>=$date OR parent.pid=$pid)\n"
+      "     ORDER BY mtime DESC LIMIT 10\n"
+      "  )\n"
+      "  INSERT OR IGNORE INTO ok SELECT rid FROM ancestor;"
+    );
+    sqlite3_close(dbAux);
+    g.db = dbMain;
+  }
+  speedtest1_end_test();
+}
+
 #ifdef SQLITE_ENABLE_RTREE
 /* Generate two numbers between 1 and mx.  The first number is less than
 ** the second.  Usually the numbers are near each other but can sometimes
@@ -2512,10 +2961,8 @@ int main(int argc, char **argv){
   int openFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE
     ;                           /* SQLITE_OPEN_xxx flags. */
   char *zTSet = "main";         /* Which --testset torun */
-  const char * zVfs = 0;        /* --vfs NAME */
   int doTrace = 0;              /* True for --trace */
   const char *zEncoding = 0;    /* --utf16be or --utf16le */
-  const char *zDbName = 0;      /* Name of the test database */
 
   void *pHeap = 0;              /* Allocated heap space */
   void *pLook = 0;              /* Allocated lookaside space */
@@ -2542,6 +2989,8 @@ int main(int argc, char **argv){
          sqlite3_libversion(), sqlite3_sourceid());
 
   /* Process command-line arguments */
+  g.zDbName = 0;
+  g.zVfs = 0;
   g.zWR = "";
   g.zNN = "";
   g.zPK = "UNIQUE";
@@ -2668,7 +3117,7 @@ int main(int argc, char **argv){
         g.eTemp = argv[i][0] - '0';
       }else if( strcmp(z,"testset")==0 ){
         static char zMix1Tests[] =
-            "main,orm/25,cte/20,json,fp/3,parsenumber/25,rtree/10,star";
+            "main,orm/25,cte/20,json,fp/3,parsenumber/25,rtree/10,star,app";
         ARGC_VALUE_CHECK(1);
         zTSet = argv[++i];
         if( strcmp(zTSet,"mix1")==0 ) zTSet = zMix1Tests;
@@ -2688,7 +3137,7 @@ int main(int argc, char **argv){
 #endif
       }else if( strcmp(z,"vfs")==0 ){
         ARGC_VALUE_CHECK(1);
-        zVfs = argv[++i];
+        g.zVfs = argv[++i];
       }else if( strcmp(z,"reserve")==0 ){
         ARGC_VALUE_CHECK(1);
         g.nReserve = atoi(argv[++i]);
@@ -2718,8 +3167,8 @@ int main(int argc, char **argv){
         fatal_error("unknown option: %s\nUse \"%s -?\" for help\n",
                     argv[i], argv[0]);
       }
-    }else if( zDbName==0 ){
-      zDbName = argv[i];
+    }else if( g.zDbName==0 ){
+      g.zDbName = argv[i];
     }else{
       fatal_error("surplus argument: %s\nUse \"%s -?\" for help\n",
                   argv[i], argv[0]);
@@ -2748,8 +3197,8 @@ int main(int argc, char **argv){
 #endif
   sqlite3_initialize();
 
-  if( zDbName!=0 ){
-    sqlite3_vfs *pVfs = sqlite3_vfs_find(zVfs);
+  if( g.zDbName!=0 ){
+    sqlite3_vfs *pVfs = sqlite3_vfs_find(g.zVfs);
     /* For some VFSes, e.g. opfs, unlink() is not sufficient. Use the
     ** selected (or default) VFS's xDelete method to delete the
     ** database. This is specifically important for the "opfs" VFS
@@ -2757,15 +3206,15 @@ int main(int argc, char **argv){
     ** can be cleaned up properly. For historical compatibility, we'll
     ** also simply unlink(). */
     if( pVfs!=0 ){
-      pVfs->xDelete(pVfs, zDbName, 1);
+      pVfs->xDelete(pVfs, g.zDbName, 1);
     }
-    unlink(zDbName);
+    unlink(g.zDbName);
   }
 
   /* Open the database and the input file */
-  if( sqlite3_open_v2(memDb ? ":memory:" : zDbName, &g.db,
-                      openFlags, zVfs) ){
-    fatal_error("Cannot open database file: %s\n", zDbName);
+  if( sqlite3_open_v2(memDb ? ":memory:" : g.zDbName, &g.db,
+                      openFlags, g.zVfs) ){
+    fatal_error("Cannot open database file: %s\n", g.zDbName);
   }
 #if SQLITE_VERSION_NUMBER>=3006001
   if( nLook>0 && szLook>0 ){
@@ -2859,6 +3308,8 @@ int main(int argc, char **argv){
       testset_cte();
     }else if( strcmp(zThisTest,"star")==0 ){
       testset_star();
+    }else if( strcmp(zThisTest,"app")==0 ){
+      testset_app();
     }else if( strcmp(zThisTest,"fp")==0 ){
       testset_fp();
     }else if( strcmp(zThisTest,"json")==0 ){