2 ** A program for performance testing.
4 ** The available command-line options are described below:
6 static const char zHelp
[] =
7 "Usage: %s [--options] DATABASE\n"
9 " --autovacuum Enable AUTOVACUUM mode\n"
10 " --cachesize N Set the cache size to N\n"
11 " --exclusive Enable locking_mode=EXCLUSIVE\n"
12 " --explain Like --sqlonly but with added EXPLAIN keywords\n"
13 " --heap SZ MIN Memory allocator uses SZ bytes & min allocation MIN\n"
14 " --incrvacuum Enable incremenatal vacuum mode\n"
15 " --journalmode M Set the journal_mode to MODE\n"
16 " --key KEY Set the encryption key to KEY\n"
17 " --lookaside N SZ Configure lookaside for N slots of SZ bytes each\n"
18 " --nosync Set PRAGMA synchronous=OFF\n"
19 " --notnull Add NOT NULL constraints to table columns\n"
20 " --pagesize N Set the page size to N\n"
21 " --pcache N SZ Configure N pages of pagecache each of size SZ bytes\n"
22 " --primarykey Use PRIMARY KEY instead of UNIQUE where appropriate\n"
23 " --reprepare Reprepare each statement upon every invocation\n"
24 " --scratch N SZ Configure scratch memory for N slots of SZ bytes each\n"
25 " --sqlonly No-op. Only show the SQL that would have been run.\n"
26 " --size N Relative test size. Default=100\n"
27 " --stats Show statistics at the end\n"
28 " --testset T Run test-set T\n"
29 " --trace Turn on SQL tracing\n"
30 " --threads N Use up to N threads for sorting\n"
31 " --utf16be Set text encoding to UTF-16BE\n"
32 " --utf16le Set text encoding to UTF-16LE\n"
33 " --verify Run additional verification steps.\n"
34 " --without-rowid Use WITHOUT ROWID where appropriate\n"
46 /* All global state is held in this structure */
47 static struct Global
{
48 sqlite3
*db
; /* The open database connection */
49 sqlite3_stmt
*pStmt
; /* Current SQL statement */
50 sqlite3_int64 iStart
; /* Start-time for the current test */
51 sqlite3_int64 iTotal
; /* Total time */
52 int bWithoutRowid
; /* True for --without-rowid */
53 int bReprepare
; /* True to reprepare the SQL on each rerun */
54 int bSqlOnly
; /* True to print the SQL once only */
55 int bExplain
; /* Print SQL with EXPLAIN prefix */
56 int bVerify
; /* Try to verify that results are correct */
57 int szTest
; /* Scale factor for test iterations */
58 const char *zWR
; /* Might be WITHOUT ROWID */
59 const char *zNN
; /* Might be NOT NULL */
60 const char *zPK
; /* Might be UNIQUE or PRIMARY KEY */
61 unsigned int x
, y
; /* Pseudo-random number generator state */
62 int nResult
; /* Size of the current result */
63 char zResult
[3000]; /* Text of the current result */
67 /* Print an error message and exit */
68 static void fatal_error(const char *zMsg
, ...){
71 vfprintf(stderr
, zMsg
, ap
);
77 ** Return the value of a hexadecimal digit. Return -1 if the input
78 ** is not a hex digit.
80 static int hexDigitValue(char c
){
81 if( c
>='0' && c
<='9' ) return c
- '0';
82 if( c
>='a' && c
<='f' ) return c
- 'a' + 10;
83 if( c
>='A' && c
<='F' ) return c
- 'A' + 10;
87 /* Provide an alternative to sqlite3_stricmp() in older versions of
89 #if SQLITE_VERSION_NUMBER<3007011
90 # define sqlite3_stricmp strcmp
94 ** Interpret zArg as an integer value, possibly with suffixes.
96 static int integerValue(const char *zArg
){
98 static const struct { char *zSuffix
; int iMult
; } aMult
[] = {
100 { "MiB", 1024*1024 },
101 { "GiB", 1024*1024*1024 },
104 { "GB", 1000000000 },
114 }else if( zArg
[0]=='+' ){
117 if( zArg
[0]=='0' && zArg
[1]=='x' ){
120 while( (x
= hexDigitValue(zArg
[0]))>=0 ){
125 while( isdigit(zArg
[0]) ){
126 v
= v
*10 + zArg
[0] - '0';
130 for(i
=0; i
<sizeof(aMult
)/sizeof(aMult
[0]); i
++){
131 if( sqlite3_stricmp(aMult
[i
].zSuffix
, zArg
)==0 ){
136 if( v
>0x7fffffff ) fatal_error("parameter too large - max 2147483648");
137 return (int)(isNeg
? -v
: v
);
140 /* Return the current wall-clock time, in milliseconds */
141 sqlite3_int64
speedtest1_timestamp(void){
142 static sqlite3_vfs
*clockVfs
= 0;
144 if( clockVfs
==0 ) clockVfs
= sqlite3_vfs_find(0);
145 #if SQLITE_VERSION_NUMBER>=3007000
146 if( clockVfs
->iVersion
>=2 && clockVfs
->xCurrentTimeInt64
!=0 ){
147 clockVfs
->xCurrentTimeInt64(clockVfs
, &t
);
152 clockVfs
->xCurrentTime(clockVfs
, &r
);
153 t
= (sqlite3_int64
)(r
*86400000.0);
158 /* Return a pseudo-random unsigned integer */
159 unsigned int speedtest1_random(void){
160 g
.x
= (g
.x
>>1) ^ ((1+~(g
.x
&1)) & 0xd0000001);
161 g
.y
= g
.y
*1103515245 + 12345;
165 /* Map the value in within the range of 1...limit into another
166 ** number in a way that is chatic and invertable.
168 unsigned swizzle(unsigned in
, unsigned limit
){
171 out
= (out
<<1) | (in
&1);
178 /* Round up a number so that it is a power of two minus one
180 unsigned roundup_allones(unsigned limit
){
182 while( m
<limit
) m
= (m
<<1)+1;
186 /* The speedtest1_numbername procedure below converts its argment (an integer)
187 ** into a string which is the English-language name for that number.
188 ** The returned string should be freed with sqlite3_free().
192 ** speedtest1_numbername(123) -> "one hundred twenty three"
194 int speedtest1_numbername(unsigned int n
, char *zOut
, int nOut
){
195 static const char *ones
[] = { "zero", "one", "two", "three", "four", "five",
196 "six", "seven", "eight", "nine", "ten", "eleven", "twelve",
197 "thirteen", "fourteen", "fifteen", "sixteen", "seventeen",
198 "eighteen", "nineteen" };
199 static const char *tens
[] = { "", "ten", "twenty", "thirty", "forty",
200 "fifty", "sixty", "seventy", "eighty", "ninety" };
204 i
+= speedtest1_numbername(n
/1000000000, zOut
+i
, nOut
-i
);
205 sqlite3_snprintf(nOut
-i
, zOut
+i
, " billion");
206 i
+= (int)strlen(zOut
+i
);
210 if( i
&& i
<nOut
-1 ) zOut
[i
++] = ' ';
211 i
+= speedtest1_numbername(n
/1000000, zOut
+i
, nOut
-i
);
212 sqlite3_snprintf(nOut
-i
, zOut
+i
, " million");
213 i
+= (int)strlen(zOut
+i
);
217 if( i
&& i
<nOut
-1 ) zOut
[i
++] = ' ';
218 i
+= speedtest1_numbername(n
/1000, zOut
+i
, nOut
-i
);
219 sqlite3_snprintf(nOut
-i
, zOut
+i
, " thousand");
220 i
+= (int)strlen(zOut
+i
);
224 if( i
&& i
<nOut
-1 ) zOut
[i
++] = ' ';
225 sqlite3_snprintf(nOut
-i
, zOut
+i
, "%s hundred", ones
[n
/100]);
226 i
+= (int)strlen(zOut
+i
);
230 if( i
&& i
<nOut
-1 ) zOut
[i
++] = ' ';
231 sqlite3_snprintf(nOut
-i
, zOut
+i
, "%s", tens
[n
/10]);
232 i
+= (int)strlen(zOut
+i
);
236 if( i
&& i
<nOut
-1 ) zOut
[i
++] = ' ';
237 sqlite3_snprintf(nOut
-i
, zOut
+i
, "%s", ones
[n
]);
238 i
+= (int)strlen(zOut
+i
);
241 sqlite3_snprintf(nOut
-i
, zOut
+i
, "zero");
242 i
+= (int)strlen(zOut
+i
);
248 /* Start a new test case */
250 static const char zDots
[] =
251 ".......................................................................";
252 void speedtest1_begin_test(int iTestNum
, const char *zTestName
, ...){
253 int n
= (int)strlen(zTestName
);
256 va_start(ap
, zTestName
);
257 zName
= sqlite3_vmprintf(zTestName
, ap
);
259 n
= (int)strlen(zName
);
261 zName
[NAMEWIDTH
] = 0;
265 printf("/* %4d - %s%.*s */\n", iTestNum
, zName
, NAMEWIDTH
-n
, zDots
);
267 printf("%4d - %s%.*s ", iTestNum
, zName
, NAMEWIDTH
-n
, zDots
);
272 g
.iStart
= speedtest1_timestamp();
277 /* Complete a test case */
278 void speedtest1_end_test(void){
279 sqlite3_int64 iElapseTime
= speedtest1_timestamp() - g
.iStart
;
281 g
.iTotal
+= iElapseTime
;
282 printf("%4d.%03ds\n", (int)(iElapseTime
/1000), (int)(iElapseTime
%1000));
285 sqlite3_finalize(g
.pStmt
);
290 /* Report end of testing */
291 void speedtest1_final(void){
293 printf(" TOTAL%.*s %4d.%03ds\n", NAMEWIDTH
-5, zDots
,
294 (int)(g
.iTotal
/1000), (int)(g
.iTotal
%1000));
298 /* Print an SQL statement to standard output */
299 static void printSql(const char *zSql
){
300 int n
= (int)strlen(zSql
);
301 while( n
>0 && (zSql
[n
-1]==';' || isspace(zSql
[n
-1])) ){ n
--; }
302 if( g
.bExplain
) printf("EXPLAIN ");
303 printf("%.*s;\n", n
, zSql
);
305 #if SQLITE_VERSION_NUMBER>=3007010
306 && ( sqlite3_strglob("CREATE *", zSql
)==0
307 || sqlite3_strglob("DROP *", zSql
)==0
308 || sqlite3_strglob("ALTER *", zSql
)==0
312 printf("%.*s;\n", n
, zSql
);
317 void speedtest1_exec(const char *zFormat
, ...){
320 va_start(ap
, zFormat
);
321 zSql
= sqlite3_vmprintf(zFormat
, ap
);
327 int rc
= sqlite3_exec(g
.db
, zSql
, 0, 0, &zErrMsg
);
328 if( zErrMsg
) fatal_error("SQL error: %s\n%s\n", zErrMsg
, zSql
);
329 if( rc
!=SQLITE_OK
) fatal_error("exec error: %s\n", sqlite3_errmsg(g
.db
));
334 /* Prepare an SQL statement */
335 void speedtest1_prepare(const char *zFormat
, ...){
338 va_start(ap
, zFormat
);
339 zSql
= sqlite3_vmprintf(zFormat
, ap
);
345 if( g
.pStmt
) sqlite3_finalize(g
.pStmt
);
346 rc
= sqlite3_prepare_v2(g
.db
, zSql
, -1, &g
.pStmt
, 0);
348 fatal_error("SQL error: %s\n", sqlite3_errmsg(g
.db
));
354 /* Run an SQL statement previously prepared */
355 void speedtest1_run(void){
357 if( g
.bSqlOnly
) return;
360 while( sqlite3_step(g
.pStmt
)==SQLITE_ROW
){
361 n
= sqlite3_column_count(g
.pStmt
);
363 const char *z
= (const char*)sqlite3_column_text(g
.pStmt
, i
);
364 if( z
==0 ) z
= "nil";
365 len
= (int)strlen(z
);
366 if( g
.nResult
+len
<sizeof(g
.zResult
)-2 ){
367 if( g
.nResult
>0 ) g
.zResult
[g
.nResult
++] = ' ';
368 memcpy(g
.zResult
+ g
.nResult
, z
, len
+1);
375 sqlite3_prepare_v2(g
.db
, sqlite3_sql(g
.pStmt
), -1, &pNew
, 0);
376 sqlite3_finalize(g
.pStmt
);
379 sqlite3_reset(g
.pStmt
);
383 /* The sqlite3_trace() callback function */
384 static void traceCallback(void *NotUsed
, const char *zSql
){
385 int n
= (int)strlen(zSql
);
386 while( n
>0 && (zSql
[n
-1]==';' || isspace(zSql
[n
-1])) ) n
--;
387 fprintf(stderr
,"%.*s;\n", n
, zSql
);
390 /* Substitute random() function that gives the same random
391 ** sequence on each run, for repeatability. */
392 static void randomFunc(
393 sqlite3_context
*context
,
395 sqlite3_value
**NotUsed2
397 sqlite3_result_int64(context
, (sqlite3_int64
)speedtest1_random());
400 /* Estimate the square root of an integer */
401 static int est_square_root(int x
){
405 for(n
=0; y0
>0 && n
<10; n
++){
414 ** The main and default testset
416 void testset_main(void){
417 int i
; /* Loop counter */
418 int n
; /* iteration count */
419 int sz
; /* Size of the tables */
420 int maxb
; /* Maximum swizzled value */
421 unsigned x1
, x2
; /* Parameters */
422 int len
; /* Length of the zNum[] string */
423 char zNum
[2000]; /* A number name */
425 sz
= n
= g
.szTest
*500;
426 maxb
= roundup_allones(sz
);
427 speedtest1_begin_test(100, "%d INSERTs into table with no index", n
);
428 speedtest1_exec("BEGIN");
429 speedtest1_exec("CREATE TABLE t1(a INTEGER %s, b INTEGER %s, c TEXT %s);",
430 g
.zNN
, g
.zNN
, g
.zNN
);
431 speedtest1_prepare("INSERT INTO t1 VALUES(?1,?2,?3); -- %d times", n
);
433 x1
= swizzle(i
,maxb
);
434 speedtest1_numbername(x1
, zNum
, sizeof(zNum
));
435 sqlite3_bind_int64(g
.pStmt
, 1, (sqlite3_int64
)x1
);
436 sqlite3_bind_int(g
.pStmt
, 2, i
);
437 sqlite3_bind_text(g
.pStmt
, 3, zNum
, -1, SQLITE_STATIC
);
440 speedtest1_exec("COMMIT");
441 speedtest1_end_test();
445 speedtest1_begin_test(110, "%d ordered INSERTS with one index/PK", n
);
446 speedtest1_exec("BEGIN");
447 speedtest1_exec("CREATE TABLE t2(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s",
448 g
.zNN
, g
.zPK
, g
.zNN
, g
.zNN
, g
.zWR
);
449 speedtest1_prepare("INSERT INTO t2 VALUES(?1,?2,?3); -- %d times", n
);
451 x1
= swizzle(i
,maxb
);
452 speedtest1_numbername(x1
, zNum
, sizeof(zNum
));
453 sqlite3_bind_int(g
.pStmt
, 1, i
);
454 sqlite3_bind_int64(g
.pStmt
, 2, (sqlite3_int64
)x1
);
455 sqlite3_bind_text(g
.pStmt
, 3, zNum
, -1, SQLITE_STATIC
);
458 speedtest1_exec("COMMIT");
459 speedtest1_end_test();
463 speedtest1_begin_test(120, "%d unordered INSERTS with one index/PK", n
);
464 speedtest1_exec("BEGIN");
465 speedtest1_exec("CREATE TABLE t3(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s",
466 g
.zNN
, g
.zPK
, g
.zNN
, g
.zNN
, g
.zWR
);
467 speedtest1_prepare("INSERT INTO t3 VALUES(?1,?2,?3); -- %d times", n
);
469 x1
= swizzle(i
,maxb
);
470 speedtest1_numbername(x1
, zNum
, sizeof(zNum
));
471 sqlite3_bind_int(g
.pStmt
, 2, i
);
472 sqlite3_bind_int64(g
.pStmt
, 1, (sqlite3_int64
)x1
);
473 sqlite3_bind_text(g
.pStmt
, 3, zNum
, -1, SQLITE_STATIC
);
476 speedtest1_exec("COMMIT");
477 speedtest1_end_test();
481 speedtest1_begin_test(130, "%d SELECTS, numeric BETWEEN, unindexed", n
);
482 speedtest1_exec("BEGIN");
484 "SELECT count(*), avg(b), sum(length(c)) FROM t1\n"
485 " WHERE b BETWEEN ?1 AND ?2; -- %d times", n
488 x1
= speedtest1_random()%maxb
;
489 x2
= speedtest1_random()%10 + sz
/5000 + x1
;
490 sqlite3_bind_int(g
.pStmt
, 1, x1
);
491 sqlite3_bind_int(g
.pStmt
, 2, x2
);
494 speedtest1_exec("COMMIT");
495 speedtest1_end_test();
499 speedtest1_begin_test(140, "%d SELECTS, LIKE, unindexed", n
);
500 speedtest1_exec("BEGIN");
502 "SELECT count(*), avg(b), sum(length(c)) FROM t1\n"
503 " WHERE c LIKE ?1; -- %d times", n
506 x1
= speedtest1_random()%maxb
;
508 len
= speedtest1_numbername(i
, zNum
+1, sizeof(zNum
)-2);
511 sqlite3_bind_text(g
.pStmt
, 1, zNum
, len
, SQLITE_STATIC
);
514 speedtest1_exec("COMMIT");
515 speedtest1_end_test();
519 speedtest1_begin_test(142, "%d SELECTS w/ORDER BY, unindexed", n
);
520 speedtest1_exec("BEGIN");
522 "SELECT a, b, c FROM t1 WHERE c LIKE ?1\n"
523 " ORDER BY a; -- %d times", n
526 x1
= speedtest1_random()%maxb
;
528 len
= speedtest1_numbername(i
, zNum
+1, sizeof(zNum
)-2);
531 sqlite3_bind_text(g
.pStmt
, 1, zNum
, len
, SQLITE_STATIC
);
534 speedtest1_exec("COMMIT");
535 speedtest1_end_test();
537 n
= 10; //g.szTest/5;
538 speedtest1_begin_test(145, "%d SELECTS w/ORDER BY and LIMIT, unindexed", n
);
539 speedtest1_exec("BEGIN");
541 "SELECT a, b, c FROM t1 WHERE c LIKE ?1\n"
542 " ORDER BY a LIMIT 10; -- %d times", n
545 x1
= speedtest1_random()%maxb
;
547 len
= speedtest1_numbername(i
, zNum
+1, sizeof(zNum
)-2);
550 sqlite3_bind_text(g
.pStmt
, 1, zNum
, len
, SQLITE_STATIC
);
553 speedtest1_exec("COMMIT");
554 speedtest1_end_test();
557 speedtest1_begin_test(150, "CREATE INDEX five times");
558 speedtest1_exec("BEGIN;");
559 speedtest1_exec("CREATE UNIQUE INDEX t1b ON t1(b);");
560 speedtest1_exec("CREATE INDEX t1c ON t1(c);");
561 speedtest1_exec("CREATE UNIQUE INDEX t2b ON t2(b);");
562 speedtest1_exec("CREATE INDEX t2c ON t2(c DESC);");
563 speedtest1_exec("CREATE INDEX t3bc ON t3(b,c);");
564 speedtest1_exec("COMMIT;");
565 speedtest1_end_test();
569 speedtest1_begin_test(160, "%d SELECTS, numeric BETWEEN, indexed", n
);
570 speedtest1_exec("BEGIN");
572 "SELECT count(*), avg(b), sum(length(c)) FROM t1\n"
573 " WHERE b BETWEEN ?1 AND ?2; -- %d times", n
576 x1
= speedtest1_random()%maxb
;
577 x2
= speedtest1_random()%10 + sz
/5000 + x1
;
578 sqlite3_bind_int(g
.pStmt
, 1, x1
);
579 sqlite3_bind_int(g
.pStmt
, 2, x2
);
582 speedtest1_exec("COMMIT");
583 speedtest1_end_test();
587 speedtest1_begin_test(161, "%d SELECTS, numeric BETWEEN, PK", n
);
588 speedtest1_exec("BEGIN");
590 "SELECT count(*), avg(b), sum(length(c)) FROM t2\n"
591 " WHERE a BETWEEN ?1 AND ?2; -- %d times", n
594 x1
= speedtest1_random()%maxb
;
595 x2
= speedtest1_random()%10 + sz
/5000 + x1
;
596 sqlite3_bind_int(g
.pStmt
, 1, x1
);
597 sqlite3_bind_int(g
.pStmt
, 2, x2
);
600 speedtest1_exec("COMMIT");
601 speedtest1_end_test();
605 speedtest1_begin_test(170, "%d SELECTS, text BETWEEN, indexed", n
);
606 speedtest1_exec("BEGIN");
608 "SELECT count(*), avg(b), sum(length(c)) FROM t1\n"
609 " WHERE c BETWEEN ?1 AND (?1||'~'); -- %d times", n
612 x1
= swizzle(i
, maxb
);
613 len
= speedtest1_numbername(x1
, zNum
, sizeof(zNum
)-1);
614 sqlite3_bind_text(g
.pStmt
, 1, zNum
, len
, SQLITE_STATIC
);
617 speedtest1_exec("COMMIT");
618 speedtest1_end_test();
621 speedtest1_begin_test(180, "%d INSERTS with three indexes", n
);
622 speedtest1_exec("BEGIN");
625 " a INTEGER %s %s,\n"
629 g
.zNN
, g
.zPK
, g
.zNN
, g
.zNN
, g
.zWR
);
630 speedtest1_exec("CREATE INDEX t4b ON t4(b)");
631 speedtest1_exec("CREATE INDEX t4c ON t4(c)");
632 speedtest1_exec("INSERT INTO t4 SELECT * FROM t1");
633 speedtest1_exec("COMMIT");
634 speedtest1_end_test();
637 speedtest1_begin_test(190, "DELETE and REFILL one table", n
);
638 speedtest1_exec("DELETE FROM t2;");
639 speedtest1_exec("INSERT INTO t2 SELECT * FROM t1;");
640 speedtest1_end_test();
643 speedtest1_begin_test(200, "VACUUM");
644 speedtest1_exec("VACUUM");
645 speedtest1_end_test();
648 speedtest1_begin_test(210, "ALTER TABLE ADD COLUMN, and query");
649 speedtest1_exec("ALTER TABLE t2 ADD COLUMN d DEFAULT 123");
650 speedtest1_exec("SELECT sum(d) FROM t2");
651 speedtest1_end_test();
655 speedtest1_begin_test(230, "%d UPDATES, numeric BETWEEN, indexed", n
);
656 speedtest1_exec("BEGIN");
658 "UPDATE t2 SET d=b*2 WHERE b BETWEEN ?1 AND ?2; -- %d times", n
661 x1
= speedtest1_random()%maxb
;
662 x2
= speedtest1_random()%10 + sz
/5000 + x1
;
663 sqlite3_bind_int(g
.pStmt
, 1, x1
);
664 sqlite3_bind_int(g
.pStmt
, 2, x2
);
667 speedtest1_exec("COMMIT");
668 speedtest1_end_test();
672 speedtest1_begin_test(240, "%d UPDATES of individual rows", n
);
673 speedtest1_exec("BEGIN");
675 "UPDATE t2 SET d=b*3 WHERE a=?1; -- %d times", n
678 x1
= speedtest1_random()%sz
+ 1;
679 sqlite3_bind_int(g
.pStmt
, 1, x1
);
682 speedtest1_exec("COMMIT");
683 speedtest1_end_test();
685 speedtest1_begin_test(250, "One big UPDATE of the whole %d-row table", sz
);
686 speedtest1_exec("UPDATE t2 SET d=b*4");
687 speedtest1_end_test();
690 speedtest1_begin_test(260, "Query added column after filling");
691 speedtest1_exec("SELECT sum(d) FROM t2");
692 speedtest1_end_test();
697 speedtest1_begin_test(270, "%d DELETEs, numeric BETWEEN, indexed", n
);
698 speedtest1_exec("BEGIN");
700 "DELETE FROM t2 WHERE b BETWEEN ?1 AND ?2; -- %d times", n
703 x1
= speedtest1_random()%maxb
+ 1;
704 x2
= speedtest1_random()%10 + sz
/5000 + x1
;
705 sqlite3_bind_int(g
.pStmt
, 1, x1
);
706 sqlite3_bind_int(g
.pStmt
, 2, x2
);
709 speedtest1_exec("COMMIT");
710 speedtest1_end_test();
714 speedtest1_begin_test(280, "%d DELETEs of individual rows", n
);
715 speedtest1_exec("BEGIN");
717 "DELETE FROM t3 WHERE a=?1; -- %d times", n
720 x1
= speedtest1_random()%sz
+ 1;
721 sqlite3_bind_int(g
.pStmt
, 1, x1
);
724 speedtest1_exec("COMMIT");
725 speedtest1_end_test();
728 speedtest1_begin_test(290, "Refill two %d-row tables using REPLACE", sz
);
729 speedtest1_exec("REPLACE INTO t2(a,b,c) SELECT a,b,c FROM t1");
730 speedtest1_exec("REPLACE INTO t3(a,b,c) SELECT a,b,c FROM t1");
731 speedtest1_end_test();
733 speedtest1_begin_test(300, "Refill a %d-row table using (b&1)==(a&1)", sz
);
734 speedtest1_exec("DELETE FROM t2;");
735 speedtest1_exec("INSERT INTO t2(a,b,c)\n"
736 " SELECT a,b,c FROM t1 WHERE (b&1)==(a&1);");
737 speedtest1_exec("INSERT INTO t2(a,b,c)\n"
738 " SELECT a,b,c FROM t1 WHERE (b&1)<>(a&1);");
739 speedtest1_end_test();
743 speedtest1_begin_test(310, "%d four-ways joins", n
);
744 speedtest1_exec("BEGIN");
746 "SELECT t1.c FROM t1, t2, t3, t4\n"
747 " WHERE t4.a BETWEEN ?1 AND ?2\n"
753 x1
= speedtest1_random()%sz
+ 1;
754 x2
= speedtest1_random()%10 + x1
+ 4;
755 sqlite3_bind_int(g
.pStmt
, 1, x1
);
756 sqlite3_bind_int(g
.pStmt
, 2, x2
);
759 speedtest1_exec("COMMIT");
760 speedtest1_end_test();
762 speedtest1_begin_test(320, "subquery in result set", n
);
764 "SELECT sum(a), max(c),\n"
765 " avg((SELECT a FROM t2 WHERE 5+t2.b=t1.b) AND rowid<?1), max(c)\n"
766 " FROM t1 WHERE rowid<?1;"
768 sqlite3_bind_int(g
.pStmt
, 1, est_square_root(g
.szTest
)*50);
770 speedtest1_end_test();
772 speedtest1_begin_test(980, "PRAGMA integrity_check");
773 speedtest1_exec("PRAGMA integrity_check");
774 speedtest1_end_test();
777 speedtest1_begin_test(990, "ANALYZE");
778 speedtest1_exec("ANALYZE");
779 speedtest1_end_test();
783 ** A testset for common table expressions. This exercises code
784 ** for views, subqueries, co-routines, etc.
786 void testset_cte(void){
787 static const char *azPuzzle
[] = {
827 }else if( g
.szTest
<70 ){
832 speedtest1_begin_test(100, "Sudoku with recursive 'digits'");
835 " input(sud) AS (VALUES(?1)),\n"
836 " digits(z,lp) AS (\n"
839 " SELECT CAST(lp+1 AS TEXT), lp+1 FROM digits WHERE lp<9\n"
842 " SELECT sud, instr(sud, '.') FROM input\n"
845 " substr(s, 1, ind-1) || z || substr(s, ind+1),\n"
846 " instr( substr(s, 1, ind-1) || z || substr(s, ind+1), '.' )\n"
847 " FROM x, digits AS z\n"
849 " AND NOT EXISTS (\n"
851 " FROM digits AS lp\n"
852 " WHERE z.z = substr(s, ((ind-1)/9)*9 + lp, 1)\n"
853 " OR z.z = substr(s, ((ind-1)%%9) + (lp-1)*9 + 1, 1)\n"
854 " OR z.z = substr(s, (((ind-1)/3) %% 3) * 3\n"
855 " + ((ind-1)/27) * 27 + lp\n"
856 " + ((lp-1) / 3) * 6, 1)\n"
859 "SELECT s FROM x WHERE ind=0;"
861 sqlite3_bind_text(g
.pStmt
, 1, zPuz
, -1, SQLITE_STATIC
);
863 speedtest1_end_test();
865 speedtest1_begin_test(200, "Sudoku with VALUES 'digits'");
868 " input(sud) AS (VALUES(?1)),\n"
869 " digits(z,lp) AS (VALUES('1',1),('2',2),('3',3),('4',4),('5',5),\n"
870 " ('6',6),('7',7),('8',8),('9',9)),\n"
872 " SELECT sud, instr(sud, '.') FROM input\n"
875 " substr(s, 1, ind-1) || z || substr(s, ind+1),\n"
876 " instr( substr(s, 1, ind-1) || z || substr(s, ind+1), '.' )\n"
877 " FROM x, digits AS z\n"
879 " AND NOT EXISTS (\n"
881 " FROM digits AS lp\n"
882 " WHERE z.z = substr(s, ((ind-1)/9)*9 + lp, 1)\n"
883 " OR z.z = substr(s, ((ind-1)%%9) + (lp-1)*9 + 1, 1)\n"
884 " OR z.z = substr(s, (((ind-1)/3) %% 3) * 3\n"
885 " + ((ind-1)/27) * 27 + lp\n"
886 " + ((lp-1) / 3) * 6, 1)\n"
889 "SELECT s FROM x WHERE ind=0;"
891 sqlite3_bind_text(g
.pStmt
, 1, zPuz
, -1, SQLITE_STATIC
);
893 speedtest1_end_test();
895 rSpacing
= 5.0/g
.szTest
;
896 speedtest1_begin_test(300, "Mandelbrot Set with spacing=%f", rSpacing
);
899 " xaxis(x) AS (VALUES(-2.0) UNION ALL SELECT x+?1 FROM xaxis WHERE x<1.2),\n"
900 " yaxis(y) AS (VALUES(-1.0) UNION ALL SELECT y+?2 FROM yaxis WHERE y<1.0),\n"
901 " m(iter, cx, cy, x, y) AS (\n"
902 " SELECT 0, x, y, 0.0, 0.0 FROM xaxis, yaxis\n"
904 " SELECT iter+1, cx, cy, x*x-y*y + cx, 2.0*x*y + cy FROM m \n"
905 " WHERE (x*x + y*y) < 4.0 AND iter<28\n"
907 " m2(iter, cx, cy) AS (\n"
908 " SELECT max(iter), cx, cy FROM m GROUP BY cx, cy\n"
911 " SELECT group_concat( substr(' .+*#', 1+min(iter/7,4), 1), '') \n"
912 " FROM m2 GROUP BY cy\n"
914 "SELECT group_concat(rtrim(t),x'0a') FROM a;"
916 sqlite3_bind_double(g
.pStmt
, 1, rSpacing
*.05);
917 sqlite3_bind_double(g
.pStmt
, 2, rSpacing
);
919 speedtest1_end_test();
921 nElem
= 10000*g
.szTest
;
922 speedtest1_begin_test(400, "EXCEPT operator on %d-element tables", nElem
);
925 " t1(x) AS (VALUES(2) UNION ALL SELECT x+2 FROM t1 WHERE x<%d),\n"
926 " t2(y) AS (VALUES(3) UNION ALL SELECT y+3 FROM t2 WHERE y<%d)\n"
927 "SELECT count(x), avg(x) FROM (\n"
928 " SELECT x FROM t1 EXCEPT SELECT y FROM t2 ORDER BY 1\n"
933 speedtest1_end_test();
937 #ifdef SQLITE_ENABLE_RTREE
938 /* Generate two numbers between 1 and mx. The first number is less than
939 ** the second. Usually the numbers are near each other but can sometimes
942 static void twoCoords(
943 int p1
, int p2
, /* Parameters adjusting sizes */
944 unsigned mx
, /* Range of 1..mx */
945 unsigned *pX0
, unsigned *pX1
/* OUT: write results here */
947 unsigned d
, x0
, x1
, span
;
950 if( speedtest1_random()%3==0 ) span
*= p1
;
951 if( speedtest1_random()%p2
==0 ) span
= mx
/2;
952 d
= speedtest1_random()%span
+ 1;
953 x0
= speedtest1_random()%(mx
-d
) + 1;
960 #ifdef SQLITE_ENABLE_RTREE
961 /* The following routine is an R-Tree geometry callback. It returns
962 ** true if the object overlaps a slice on the Y coordinate between the
963 ** two values given as arguments. In other words
965 ** SELECT count(*) FROM rt1 WHERE id MATCH xslice(10,20);
967 ** Is the same as saying:
969 ** SELECT count(*) FROM rt1 WHERE y1>=10 AND y0<=20;
971 static int xsliceGeometryCallback(
972 sqlite3_rtree_geometry
*p
,
977 *pRes
= aCoord
[3]>=p
->aParam
[0] && aCoord
[2]<=p
->aParam
[1];
980 #endif /* SQLITE_ENABLE_RTREE */
982 #ifdef SQLITE_ENABLE_RTREE
984 ** A testset for the R-Tree virtual table
986 void testset_rtree(int p1
, int p2
){
989 unsigned x0
, x1
, y0
, y1
, z0
, z1
;
991 int *aCheck
= sqlite3_malloc( sizeof(int)*g
.szTest
*100 );
995 speedtest1_begin_test(100, "%d INSERTs into an r-tree", n
);
996 speedtest1_exec("BEGIN");
997 speedtest1_exec("CREATE VIRTUAL TABLE rt1 USING rtree(id,x0,x1,y0,y1,z0,z1)");
998 speedtest1_prepare("INSERT INTO rt1(id,x0,x1,y0,y1,z0,z1)"
999 "VALUES(?1,?2,?3,?4,?5,?6,?7)");
1000 for(i
=1; i
<=n
; i
++){
1001 twoCoords(p1
, p2
, mxCoord
, &x0
, &x1
);
1002 twoCoords(p1
, p2
, mxCoord
, &y0
, &y1
);
1003 twoCoords(p1
, p2
, mxCoord
, &z0
, &z1
);
1004 sqlite3_bind_int(g
.pStmt
, 1, i
);
1005 sqlite3_bind_int(g
.pStmt
, 2, x0
);
1006 sqlite3_bind_int(g
.pStmt
, 3, x1
);
1007 sqlite3_bind_int(g
.pStmt
, 4, y0
);
1008 sqlite3_bind_int(g
.pStmt
, 5, y1
);
1009 sqlite3_bind_int(g
.pStmt
, 6, z0
);
1010 sqlite3_bind_int(g
.pStmt
, 7, z1
);
1013 speedtest1_exec("COMMIT");
1014 speedtest1_end_test();
1016 speedtest1_begin_test(101, "Copy from rtree to a regular table");
1017 speedtest1_exec("CREATE TABLE t1(id INTEGER PRIMARY KEY,x0,x1,y0,y1,z0,z1)");
1018 speedtest1_exec("INSERT INTO t1 SELECT * FROM rt1");
1019 speedtest1_end_test();
1022 speedtest1_begin_test(110, "%d one-dimensional intersect slice queries", n
);
1023 speedtest1_prepare("SELECT count(*) FROM rt1 WHERE x0>=?1 AND x1<=?2");
1026 sqlite3_bind_int(g
.pStmt
, 1, i
*iStep
);
1027 sqlite3_bind_int(g
.pStmt
, 2, (i
+1)*iStep
);
1029 aCheck
[i
] = atoi(g
.zResult
);
1031 speedtest1_end_test();
1035 speedtest1_begin_test(111, "Verify result from 1-D intersect slice queries");
1036 speedtest1_prepare("SELECT count(*) FROM t1 WHERE x0>=?1 AND x1<=?2");
1039 sqlite3_bind_int(g
.pStmt
, 1, i
*iStep
);
1040 sqlite3_bind_int(g
.pStmt
, 2, (i
+1)*iStep
);
1042 if( aCheck
[i
]!=atoi(g
.zResult
) ){
1043 fatal_error("Count disagree step %d: %d..%d. %d vs %d",
1044 i
, i
*iStep
, (i
+1)*iStep
, aCheck
[i
], atoi(g
.zResult
));
1047 speedtest1_end_test();
1051 speedtest1_begin_test(120, "%d one-dimensional overlap slice queries", n
);
1052 speedtest1_prepare("SELECT count(*) FROM rt1 WHERE y1>=?1 AND y0<=?2");
1055 sqlite3_bind_int(g
.pStmt
, 1, i
*iStep
);
1056 sqlite3_bind_int(g
.pStmt
, 2, (i
+1)*iStep
);
1058 aCheck
[i
] = atoi(g
.zResult
);
1060 speedtest1_end_test();
1064 speedtest1_begin_test(121, "Verify result from 1-D overlap slice queries");
1065 speedtest1_prepare("SELECT count(*) FROM t1 WHERE y1>=?1 AND y0<=?2");
1068 sqlite3_bind_int(g
.pStmt
, 1, i
*iStep
);
1069 sqlite3_bind_int(g
.pStmt
, 2, (i
+1)*iStep
);
1071 if( aCheck
[i
]!=atoi(g
.zResult
) ){
1072 fatal_error("Count disagree step %d: %d..%d. %d vs %d",
1073 i
, i
*iStep
, (i
+1)*iStep
, aCheck
[i
], atoi(g
.zResult
));
1076 speedtest1_end_test();
1081 speedtest1_begin_test(125, "%d custom geometry callback queries", n
);
1082 sqlite3_rtree_geometry_callback(g
.db
, "xslice", xsliceGeometryCallback
, 0);
1083 speedtest1_prepare("SELECT count(*) FROM rt1 WHERE id MATCH xslice(?1,?2)");
1086 sqlite3_bind_int(g
.pStmt
, 1, i
*iStep
);
1087 sqlite3_bind_int(g
.pStmt
, 2, (i
+1)*iStep
);
1089 if( aCheck
[i
]!=atoi(g
.zResult
) ){
1090 fatal_error("Count disagree step %d: %d..%d. %d vs %d",
1091 i
, i
*iStep
, (i
+1)*iStep
, aCheck
[i
], atoi(g
.zResult
));
1094 speedtest1_end_test();
1097 speedtest1_begin_test(130, "%d three-dimensional intersect box queries", n
);
1098 speedtest1_prepare("SELECT count(*) FROM rt1 WHERE x1>=?1 AND x0<=?2"
1099 " AND y1>=?1 AND y0<=?2 AND z1>=?1 AND z0<=?2");
1102 sqlite3_bind_int(g
.pStmt
, 1, i
*iStep
);
1103 sqlite3_bind_int(g
.pStmt
, 2, (i
+1)*iStep
);
1105 aCheck
[i
] = atoi(g
.zResult
);
1107 speedtest1_end_test();
1110 speedtest1_begin_test(140, "%d rowid queries", n
);
1111 speedtest1_prepare("SELECT * FROM rt1 WHERE id=?1");
1112 for(i
=1; i
<=n
; i
++){
1113 sqlite3_bind_int(g
.pStmt
, 1, i
);
1116 speedtest1_end_test();
1118 #endif /* SQLITE_ENABLE_RTREE */
1121 ** A testset used for debugging speedtest1 itself.
1123 void testset_debug1(void){
1126 char zNum
[2000]; /* A number name */
1129 for(i
=1; i
<=n
; i
++){
1131 x2
= swizzle(x1
, n
);
1132 speedtest1_numbername(x1
, zNum
, sizeof(zNum
));
1133 printf("%5d %5d %5d %s\n", i
, x1
, x2
, zNum
);
1137 int main(int argc
, char **argv
){
1138 int doAutovac
= 0; /* True for --autovacuum */
1139 int cacheSize
= 0; /* Desired cache size. 0 means default */
1140 int doExclusive
= 0; /* True for --exclusive */
1141 int nHeap
= 0, mnHeap
= 0; /* Heap size from --heap */
1142 int doIncrvac
= 0; /* True for --incrvacuum */
1143 const char *zJMode
= 0; /* Journal mode */
1144 const char *zKey
= 0; /* Encryption key */
1145 int nLook
= 0, szLook
= 0; /* --lookaside configuration */
1146 int noSync
= 0; /* True for --nosync */
1147 int pageSize
= 0; /* Desired page size. 0 means default */
1148 int nPCache
= 0, szPCache
= 0;/* --pcache configuration */
1149 int nScratch
= 0, szScratch
=0;/* --scratch configuration */
1150 int showStats
= 0; /* True for --stats */
1151 int nThread
= 0; /* --threads value */
1152 const char *zTSet
= "main"; /* Which --testset torun */
1153 int doTrace
= 0; /* True for --trace */
1154 const char *zEncoding
= 0; /* --utf16be or --utf16le */
1155 const char *zDbName
= 0; /* Name of the test database */
1157 void *pHeap
= 0; /* Allocated heap space */
1158 void *pLook
= 0; /* Allocated lookaside space */
1159 void *pPCache
= 0; /* Allocated storage for pcache */
1160 void *pScratch
= 0; /* Allocated storage for scratch */
1161 int iCur
, iHi
; /* Stats values, current and "highwater" */
1162 int i
; /* Loop counter */
1163 int rc
; /* API return code */
1165 /* Process command-line arguments */
1170 for(i
=1; i
<argc
; i
++){
1171 const char *z
= argv
[i
];
1173 do{ z
++; }while( z
[0]=='-' );
1174 if( strcmp(z
,"autovacuum")==0 ){
1176 }else if( strcmp(z
,"cachesize")==0 ){
1177 if( i
>=argc
-1 ) fatal_error("missing argument on %s\n", argv
[i
]);
1179 cacheSize
= integerValue(argv
[i
]);
1180 }else if( strcmp(z
,"exclusive")==0 ){
1182 }else if( strcmp(z
,"explain")==0 ){
1185 }else if( strcmp(z
,"heap")==0 ){
1186 if( i
>=argc
-2 ) fatal_error("missing arguments on %s\n", argv
[i
]);
1187 nHeap
= integerValue(argv
[i
+1]);
1188 mnHeap
= integerValue(argv
[i
+2]);
1190 }else if( strcmp(z
,"incrvacuum")==0 ){
1192 }else if( strcmp(z
,"journal")==0 ){
1193 if( i
>=argc
-1 ) fatal_error("missing argument on %s\n", argv
[i
]);
1195 }else if( strcmp(z
,"key")==0 ){
1196 if( i
>=argc
-1 ) fatal_error("missing argument on %s\n", argv
[i
]);
1198 }else if( strcmp(z
,"lookaside")==0 ){
1199 if( i
>=argc
-2 ) fatal_error("missing arguments on %s\n", argv
[i
]);
1200 nLook
= integerValue(argv
[i
+1]);
1201 szLook
= integerValue(argv
[i
+2]);
1203 }else if( strcmp(z
,"nosync")==0 ){
1205 }else if( strcmp(z
,"notnull")==0 ){
1207 }else if( strcmp(z
,"pagesize")==0 ){
1208 if( i
>=argc
-1 ) fatal_error("missing argument on %s\n", argv
[i
]);
1209 pageSize
= integerValue(argv
[++i
]);
1210 }else if( strcmp(z
,"pcache")==0 ){
1211 if( i
>=argc
-2 ) fatal_error("missing arguments on %s\n", argv
[i
]);
1212 nPCache
= integerValue(argv
[i
+1]);
1213 szPCache
= integerValue(argv
[i
+2]);
1215 }else if( strcmp(z
,"primarykey")==0 ){
1216 g
.zPK
= "PRIMARY KEY";
1217 }else if( strcmp(z
,"reprepare")==0 ){
1219 }else if( strcmp(z
,"scratch")==0 ){
1220 if( i
>=argc
-2 ) fatal_error("missing arguments on %s\n", argv
[i
]);
1221 nScratch
= integerValue(argv
[i
+1]);
1222 szScratch
= integerValue(argv
[i
+2]);
1224 }else if( strcmp(z
,"sqlonly")==0 ){
1226 }else if( strcmp(z
,"size")==0 ){
1227 if( i
>=argc
-1 ) fatal_error("missing argument on %s\n", argv
[i
]);
1228 g
.szTest
= integerValue(argv
[++i
]);
1229 }else if( strcmp(z
,"stats")==0 ){
1231 }else if( strcmp(z
,"testset")==0 ){
1232 if( i
>=argc
-1 ) fatal_error("missing argument on %s\n", argv
[i
]);
1234 }else if( strcmp(z
,"trace")==0 ){
1236 }else if( strcmp(z
,"threads")==0 ){
1237 if( i
>=argc
-1 ) fatal_error("missing argument on %s\n", argv
[i
]);
1238 nThread
= integerValue(argv
[++i
]);
1239 }else if( strcmp(z
,"utf16le")==0 ){
1240 zEncoding
= "utf16le";
1241 }else if( strcmp(z
,"utf16be")==0 ){
1242 zEncoding
= "utf16be";
1243 }else if( strcmp(z
,"verify")==0 ){
1245 }else if( strcmp(z
,"without-rowid")==0 ){
1246 g
.zWR
= "WITHOUT ROWID";
1247 g
.zPK
= "PRIMARY KEY";
1248 }else if( strcmp(z
, "help")==0 || strcmp(z
,"?")==0 ){
1249 printf(zHelp
, argv
[0]);
1252 fatal_error("unknown option: %s\nUse \"%s -?\" for help\n",
1255 }else if( zDbName
==0 ){
1258 fatal_error("surplus argument: %s\nUse \"%s -?\" for help\n",
1264 fatal_error(zHelp
, argv
[0]);
1268 pHeap
= malloc( nHeap
);
1269 if( pHeap
==0 ) fatal_error("cannot allocate %d-byte heap\n", nHeap
);
1270 rc
= sqlite3_config(SQLITE_CONFIG_HEAP
, pHeap
, nHeap
, mnHeap
);
1271 if( rc
) fatal_error("heap configuration failed: %d\n", rc
);
1273 if( nPCache
>0 && szPCache
>0 ){
1274 pPCache
= malloc( nPCache
*(sqlite3_int64
)szPCache
);
1275 if( pPCache
==0 ) fatal_error("cannot allocate %lld-byte pcache\n",
1276 nPCache
*(sqlite3_int64
)szPCache
);
1277 rc
= sqlite3_config(SQLITE_CONFIG_PAGECACHE
, pPCache
, szPCache
, nPCache
);
1278 if( rc
) fatal_error("pcache configuration failed: %d\n", rc
);
1280 if( nScratch
>0 && szScratch
>0 ){
1281 pScratch
= malloc( nScratch
*(sqlite3_int64
)szScratch
);
1282 if( pScratch
==0 ) fatal_error("cannot allocate %lld-byte scratch\n",
1283 nScratch
*(sqlite3_int64
)szScratch
);
1284 rc
= sqlite3_config(SQLITE_CONFIG_SCRATCH
, pScratch
, szScratch
, nScratch
);
1285 if( rc
) fatal_error("scratch configuration failed: %d\n", rc
);
1288 sqlite3_config(SQLITE_CONFIG_LOOKASIDE
, 0, 0);
1291 /* Open the database and the input file */
1292 if( sqlite3_open(zDbName
, &g
.db
) ){
1293 fatal_error("Cannot open database file: %s\n", zDbName
);
1295 if( nLook
>0 && szLook
>0 ){
1296 pLook
= malloc( nLook
*szLook
);
1297 rc
= sqlite3_db_config(g
.db
, SQLITE_DBCONFIG_LOOKASIDE
, pLook
, szLook
,nLook
);
1298 if( rc
) fatal_error("lookaside configuration failed: %d\n", rc
);
1301 /* Set database connection options */
1302 sqlite3_create_function(g
.db
, "random", 0, SQLITE_UTF8
, 0, randomFunc
, 0, 0);
1303 if( doTrace
) sqlite3_trace(g
.db
, traceCallback
, 0);
1304 speedtest1_exec("PRAGMA threads=%d", nThread
);
1306 speedtest1_exec("PRAGMA key('%s')", zKey
);
1309 speedtest1_exec("PRAGMA encoding=%s", zEncoding
);
1312 speedtest1_exec("PRAGMA auto_vacuum=FULL");
1313 }else if( doIncrvac
){
1314 speedtest1_exec("PRAGMA auto_vacuum=INCREMENTAL");
1317 speedtest1_exec("PRAGMA page_size=%d", pageSize
);
1320 speedtest1_exec("PRAGMA cache_size=%d", cacheSize
);
1322 if( noSync
) speedtest1_exec("PRAGMA synchronous=OFF");
1324 speedtest1_exec("PRAGMA locking_mode=EXCLUSIVE");
1327 speedtest1_exec("PRAGMA journal_mode=%s", zJMode
);
1330 if( g
.bExplain
) printf(".explain\n.echo on\n");
1331 if( strcmp(zTSet
,"main")==0 ){
1333 }else if( strcmp(zTSet
,"debug1")==0 ){
1335 }else if( strcmp(zTSet
,"cte")==0 ){
1337 }else if( strcmp(zTSet
,"rtree")==0 ){
1338 #ifdef SQLITE_ENABLE_RTREE
1339 testset_rtree(6, 147);
1341 fatal_error("compile with -DSQLITE_ENABLE_RTREE to enable "
1342 "the R-Tree tests\n");
1345 fatal_error("unknown testset: \"%s\"\nChoices: main debug1 cte rtree\n",
1350 /* Database connection statistics printed after both prepared statements
1351 ** have been finalized */
1352 #if SQLITE_VERSION_NUMBER>=3007009
1354 sqlite3_db_status(g
.db
, SQLITE_DBSTATUS_LOOKASIDE_USED
, &iCur
, &iHi
, 0);
1355 printf("-- Lookaside Slots Used: %d (max %d)\n", iCur
,iHi
);
1356 sqlite3_db_status(g
.db
, SQLITE_DBSTATUS_LOOKASIDE_HIT
, &iCur
, &iHi
, 0);
1357 printf("-- Successful lookasides: %d\n", iHi
);
1358 sqlite3_db_status(g
.db
, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE
, &iCur
,&iHi
,0);
1359 printf("-- Lookaside size faults: %d\n", iHi
);
1360 sqlite3_db_status(g
.db
, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL
, &iCur
,&iHi
,0);
1361 printf("-- Lookaside OOM faults: %d\n", iHi
);
1362 sqlite3_db_status(g
.db
, SQLITE_DBSTATUS_CACHE_USED
, &iCur
, &iHi
, 0);
1363 printf("-- Pager Heap Usage: %d bytes\n", iCur
);
1364 sqlite3_db_status(g
.db
, SQLITE_DBSTATUS_CACHE_HIT
, &iCur
, &iHi
, 1);
1365 printf("-- Page cache hits: %d\n", iCur
);
1366 sqlite3_db_status(g
.db
, SQLITE_DBSTATUS_CACHE_MISS
, &iCur
, &iHi
, 1);
1367 printf("-- Page cache misses: %d\n", iCur
);
1368 #if SQLITE_VERSION_NUMBER>=3007012
1369 sqlite3_db_status(g
.db
, SQLITE_DBSTATUS_CACHE_WRITE
, &iCur
, &iHi
, 1);
1370 printf("-- Page cache writes: %d\n", iCur
);
1372 sqlite3_db_status(g
.db
, SQLITE_DBSTATUS_SCHEMA_USED
, &iCur
, &iHi
, 0);
1373 printf("-- Schema Heap Usage: %d bytes\n", iCur
);
1374 sqlite3_db_status(g
.db
, SQLITE_DBSTATUS_STMT_USED
, &iCur
, &iHi
, 0);
1375 printf("-- Statement Heap Usage: %d bytes\n", iCur
);
1379 sqlite3_close(g
.db
);
1381 /* Global memory usage statistics printed after the database connection
1382 ** has closed. Memory usage should be zero at this point. */
1384 sqlite3_status(SQLITE_STATUS_MEMORY_USED
, &iCur
, &iHi
, 0);
1385 printf("-- Memory Used (bytes): %d (max %d)\n", iCur
,iHi
);
1386 #if SQLITE_VERSION_NUMBER>=3007000
1387 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT
, &iCur
, &iHi
, 0);
1388 printf("-- Outstanding Allocations: %d (max %d)\n", iCur
,iHi
);
1390 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW
, &iCur
, &iHi
, 0);
1391 printf("-- Pcache Overflow Bytes: %d (max %d)\n", iCur
,iHi
);
1392 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW
, &iCur
, &iHi
, 0);
1393 printf("-- Scratch Overflow Bytes: %d (max %d)\n", iCur
,iHi
);
1394 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE
, &iCur
, &iHi
, 0);
1395 printf("-- Largest Allocation: %d bytes\n",iHi
);
1396 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE
, &iCur
, &iHi
, 0);
1397 printf("-- Largest Pcache Allocation: %d bytes\n",iHi
);
1398 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE
, &iCur
, &iHi
, 0);
1399 printf("-- Largest Scratch Allocation: %d bytes\n", iHi
);
1402 /* Release memory */