/ Hex Artifact Content
Login

Artifact d8c11da184b1a13d0456d786e70b3867e141b74a:


0000: 23 20 52 75 6e 20 74 68 69 73 20 54 43 4c 20 73  # Run this TCL s
0010: 63 72 69 70 74 20 75 73 69 6e 67 20 22 74 65 73  cript using "tes
0020: 74 66 69 78 74 75 72 65 22 20 69 6e 20 6f 72 64  tfixture" in ord
0030: 65 72 20 67 65 74 20 61 20 72 65 70 6f 72 74 20  er get a report 
0040: 74 68 61 74 20 73 68 6f 77 73 0a 23 20 68 6f 77  that shows.# how
0050: 20 6d 75 63 68 20 64 69 73 6b 20 73 70 61 63 65   much disk space
0060: 20 69 73 20 75 73 65 64 20 62 79 20 61 20 70 61   is used by a pa
0070: 72 74 69 63 75 6c 61 72 20 64 61 74 61 20 74 6f  rticular data to
0080: 20 61 63 74 75 61 6c 6c 79 20 73 74 6f 72 65 20   actually store 
0090: 64 61 74 61 0a 23 20 76 65 72 73 75 73 20 68 6f  data.# versus ho
00a0: 77 20 6d 75 63 68 20 73 70 61 63 65 20 69 73 20  w much space is 
00b0: 75 6e 75 73 65 64 2e 0a 23 0a 0a 69 66 20 7b 5b  unused..#..if {[
00c0: 63 61 74 63 68 20 7b 0a 23 20 47 65 74 20 74 68  catch {.# Get th
00d0: 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 64 61  e name of the da
00e0: 74 61 62 61 73 65 20 74 6f 20 61 6e 61 6c 79 7a  tabase to analyz
00f0: 65 0a 23 0a 70 72 6f 63 20 75 73 61 67 65 20 7b  e.#.proc usage {
0100: 7d 20 7b 0a 20 20 73 65 74 20 61 72 67 76 30 20  } {.  set argv0 
0110: 5b 66 69 6c 65 20 72 6f 6f 74 6e 61 6d 65 20 5b  [file rootname [
0120: 66 69 6c 65 20 74 61 69 6c 20 5b 69 6e 66 6f 20  file tail [info 
0130: 6e 61 6d 65 6f 66 65 78 65 63 75 74 61 62 6c 65  nameofexecutable
0140: 5d 5d 5d 0a 20 20 70 75 74 73 20 73 74 64 65 72  ]]].  puts stder
0150: 72 20 22 55 73 61 67 65 3a 20 24 61 72 67 76 30  r "Usage: $argv0
0160: 20 64 61 74 61 62 61 73 65 2d 6e 61 6d 65 22 0a   database-name".
0170: 20 20 65 78 69 74 20 31 0a 7d 0a 73 65 74 20 66    exit 1.}.set f
0180: 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 20 7b  ile_to_analyze {
0190: 7d 0a 73 65 74 20 66 6c 61 67 73 28 2d 70 61 67  }.set flags(-pag
01a0: 65 69 6e 66 6f 29 20 30 0a 73 65 74 20 66 6c 61  einfo) 0.set fla
01b0: 67 73 28 2d 73 74 61 74 73 29 20 30 0a 61 70 70  gs(-stats) 0.app
01c0: 65 6e 64 20 61 72 67 76 20 7b 7d 0a 66 6f 72 65  end argv {}.fore
01d0: 61 63 68 20 61 72 67 20 24 61 72 67 76 20 7b 0a  ach arg $argv {.
01e0: 20 20 69 66 20 7b 5b 72 65 67 65 78 70 20 7b 5e    if {[regexp {^
01f0: 2d 2b 70 61 67 65 69 6e 66 6f 24 7d 20 24 61 72  -+pageinfo$} $ar
0200: 67 5d 7d 20 7b 0a 20 20 20 20 73 65 74 20 66 6c  g]} {.    set fl
0210: 61 67 73 28 2d 70 61 67 65 69 6e 66 6f 29 20 31  ags(-pageinfo) 1
0220: 0a 20 20 7d 20 65 6c 73 65 69 66 20 7b 5b 72 65  .  } elseif {[re
0230: 67 65 78 70 20 7b 5e 2d 2b 73 74 61 74 73 24 7d  gexp {^-+stats$}
0240: 20 24 61 72 67 5d 7d 20 7b 0a 20 20 20 20 73 65   $arg]} {.    se
0250: 74 20 66 6c 61 67 73 28 2d 73 74 61 74 73 29 20  t flags(-stats) 
0260: 31 0a 20 20 7d 20 65 6c 73 65 69 66 20 7b 5b 72  1.  } elseif {[r
0270: 65 67 65 78 70 20 7b 5e 2d 7d 20 24 61 72 67 5d  egexp {^-} $arg]
0280: 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 73 74 64  } {.    puts std
0290: 65 72 72 20 22 55 6e 6b 6e 6f 77 6e 20 6f 70 74  err "Unknown opt
02a0: 69 6f 6e 3a 20 24 61 72 67 22 0a 20 20 20 20 75  ion: $arg".    u
02b0: 73 61 67 65 0a 20 20 7d 20 65 6c 73 65 69 66 20  sage.  } elseif 
02c0: 7b 24 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a  {$file_to_analyz
02d0: 65 21 3d 22 22 7d 20 7b 0a 20 20 20 20 75 73 61  e!=""} {.    usa
02e0: 67 65 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20  ge.  } else {.  
02f0: 20 20 73 65 74 20 66 69 6c 65 5f 74 6f 5f 61 6e    set file_to_an
0300: 61 6c 79 7a 65 20 24 61 72 67 0a 20 20 7d 0a 7d  alyze $arg.  }.}
0310: 0a 69 66 20 7b 24 66 69 6c 65 5f 74 6f 5f 61 6e  .if {$file_to_an
0320: 61 6c 79 7a 65 3d 3d 22 22 7d 20 75 73 61 67 65  alyze==""} usage
0330: 0a 73 65 74 20 72 6f 6f 74 5f 66 69 6c 65 6e 61  .set root_filena
0340: 6d 65 20 24 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c  me $file_to_anal
0350: 79 7a 65 0a 72 65 67 65 78 70 20 7b 5e 66 69 6c  yze.regexp {^fil
0360: 65 3a 28 2f 2f 29 3f 28 5b 5e 3f 5d 2a 29 7d 20  e:(//)?([^?]*)} 
0370: 24 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65  $file_to_analyze
0380: 20 61 6c 6c 20 78 31 20 72 6f 6f 74 5f 66 69 6c   all x1 root_fil
0390: 65 6e 61 6d 65 0a 69 66 20 7b 21 5b 66 69 6c 65  ename.if {![file
03a0: 20 65 78 69 73 74 73 20 24 72 6f 6f 74 5f 66 69   exists $root_fi
03b0: 6c 65 6e 61 6d 65 5d 7d 20 7b 0a 20 20 70 75 74  lename]} {.  put
03c0: 73 20 73 74 64 65 72 72 20 22 4e 6f 20 73 75 63  s stderr "No suc
03d0: 68 20 66 69 6c 65 3a 20 24 72 6f 6f 74 5f 66 69  h file: $root_fi
03e0: 6c 65 6e 61 6d 65 22 0a 20 20 65 78 69 74 20 31  lename".  exit 1
03f0: 0a 7d 0a 69 66 20 7b 21 5b 66 69 6c 65 20 72 65  .}.if {![file re
0400: 61 64 61 62 6c 65 20 24 72 6f 6f 74 5f 66 69 6c  adable $root_fil
0410: 65 6e 61 6d 65 5d 7d 20 7b 0a 20 20 70 75 74 73  ename]} {.  puts
0420: 20 73 74 64 65 72 72 20 22 46 69 6c 65 20 69 73   stderr "File is
0430: 20 6e 6f 74 20 72 65 61 64 61 62 6c 65 3a 20 24   not readable: $
0440: 72 6f 6f 74 5f 66 69 6c 65 6e 61 6d 65 22 0a 20  root_filename". 
0450: 20 65 78 69 74 20 31 0a 7d 0a 73 65 74 20 74 72   exit 1.}.set tr
0460: 75 65 5f 66 69 6c 65 5f 73 69 7a 65 20 5b 66 69  ue_file_size [fi
0470: 6c 65 20 73 69 7a 65 20 24 72 6f 6f 74 5f 66 69  le size $root_fi
0480: 6c 65 6e 61 6d 65 5d 0a 69 66 20 7b 24 74 72 75  lename].if {$tru
0490: 65 5f 66 69 6c 65 5f 73 69 7a 65 3c 35 31 32 7d  e_file_size<512}
04a0: 20 7b 0a 20 20 70 75 74 73 20 73 74 64 65 72 72   {.  puts stderr
04b0: 20 22 45 6d 70 74 79 20 6f 72 20 6d 61 6c 66 6f   "Empty or malfo
04c0: 72 6d 65 64 20 64 61 74 61 62 61 73 65 3a 20 24  rmed database: $
04d0: 72 6f 6f 74 5f 66 69 6c 65 6e 61 6d 65 22 0a 20  root_filename". 
04e0: 20 65 78 69 74 20 31 0a 7d 0a 0a 23 20 43 6f 6d   exit 1.}..# Com
04f0: 70 75 74 65 20 74 68 65 20 74 6f 74 61 6c 20 66  pute the total f
0500: 69 6c 65 20 73 69 7a 65 20 61 73 73 75 6d 69 6e  ile size assumin
0510: 67 20 74 65 73 74 5f 6d 75 6c 74 69 70 6c 65 78  g test_multiplex
0520: 6f 72 20 69 73 20 62 65 69 6e 67 20 75 73 65 64  or is being used
0530: 2e 0a 23 20 41 73 73 75 6d 65 20 74 68 61 74 20  ..# Assume that 
0540: 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 38 5f  SQLITE_ENABLE_8_
0550: 33 5f 4e 41 4d 45 53 20 6d 69 67 68 74 20 62 65  3_NAMES might be
0560: 20 65 6e 61 62 6c 65 64 0a 23 0a 73 65 74 20 65   enabled.#.set e
0570: 78 74 65 6e 73 69 6f 6e 20 5b 66 69 6c 65 20 65  xtension [file e
0580: 78 74 65 6e 73 69 6f 6e 20 24 72 6f 6f 74 5f 66  xtension $root_f
0590: 69 6c 65 6e 61 6d 65 5d 0a 73 65 74 20 70 61 74  ilename].set pat
05a0: 74 65 72 6e 20 24 72 6f 6f 74 5f 66 69 6c 65 6e  tern $root_filen
05b0: 61 6d 65 0a 61 70 70 65 6e 64 20 70 61 74 74 65  ame.append patte
05c0: 72 6e 20 7b 5b 30 2d 33 5d 5b 30 2d 39 5d 5b 30  rn {[0-3][0-9][0
05d0: 2d 39 5d 7d 0a 66 6f 72 65 61 63 68 20 66 20 5b  -9]}.foreach f [
05e0: 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e  glob -nocomplain
05f0: 20 24 70 61 74 74 65 72 6e 5d 20 7b 0a 20 20 69   $pattern] {.  i
0600: 6e 63 72 20 74 72 75 65 5f 66 69 6c 65 5f 73 69  ncr true_file_si
0610: 7a 65 20 5b 66 69 6c 65 20 73 69 7a 65 20 24 66  ze [file size $f
0620: 5d 0a 20 20 73 65 74 20 65 78 74 65 6e 73 69 6f  ].  set extensio
0630: 6e 20 7b 7d 0a 7d 0a 69 66 20 7b 5b 73 74 72 69  n {}.}.if {[stri
0640: 6e 67 20 6c 65 6e 67 74 68 20 24 65 78 74 65 6e  ng length $exten
0650: 73 69 6f 6e 5d 3e 3d 32 20 26 26 20 5b 73 74 72  sion]>=2 && [str
0660: 69 6e 67 20 6c 65 6e 67 74 68 20 24 65 78 74 65  ing length $exte
0670: 6e 73 69 6f 6e 5d 3c 3d 34 7d 20 7b 0a 20 20 73  nsion]<=4} {.  s
0680: 65 74 20 70 61 74 74 65 72 6e 20 5b 66 69 6c 65  et pattern [file
0690: 20 72 6f 6f 74 6e 61 6d 65 20 24 72 6f 6f 74 5f   rootname $root_
06a0: 66 69 6c 65 6e 61 6d 65 5d 0a 20 20 61 70 70 65  filename].  appe
06b0: 6e 64 20 70 61 74 74 65 72 6e 20 7b 2e 5b 30 2d  nd pattern {.[0-
06c0: 33 5d 5b 30 2d 39 5d 5b 30 2d 39 5d 7d 0a 20 20  3][0-9][0-9]}.  
06d0: 66 6f 72 65 61 63 68 20 66 20 5b 67 6c 6f 62 20  foreach f [glob 
06e0: 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 24 70 61 74  -nocomplain $pat
06f0: 74 65 72 6e 5d 20 7b 0a 20 20 20 20 69 6e 63 72  tern] {.    incr
0700: 20 74 72 75 65 5f 66 69 6c 65 5f 73 69 7a 65 20   true_file_size 
0710: 5b 66 69 6c 65 20 73 69 7a 65 20 24 66 5d 0a 20  [file size $f]. 
0720: 20 7d 0a 7d 0a 0a 23 20 4f 70 65 6e 20 74 68 65   }.}..# Open the
0730: 20 64 61 74 61 62 61 73 65 0a 23 0a 69 66 20 7b   database.#.if {
0740: 5b 63 61 74 63 68 20 7b 73 71 6c 69 74 65 33 20  [catch {sqlite3 
0750: 64 62 20 24 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c  db $file_to_anal
0760: 79 7a 65 20 2d 75 72 69 20 31 7d 20 6d 73 67 5d  yze -uri 1} msg]
0770: 7d 20 7b 0a 20 20 70 75 74 73 20 73 74 64 65 72  } {.  puts stder
0780: 72 20 22 65 72 72 6f 72 20 74 72 79 69 6e 67 20  r "error trying 
0790: 74 6f 20 6f 70 65 6e 20 24 66 69 6c 65 5f 74 6f  to open $file_to
07a0: 5f 61 6e 61 6c 79 7a 65 3a 20 24 6d 73 67 22 0a  _analyze: $msg".
07b0: 20 20 65 78 69 74 20 31 0a 7d 0a 72 65 67 69 73    exit 1.}.regis
07c0: 74 65 72 5f 64 62 73 74 61 74 5f 76 74 61 62 20  ter_dbstat_vtab 
07d0: 64 62 0a 0a 64 62 20 65 76 61 6c 20 7b 53 45 4c  db..db eval {SEL
07e0: 45 43 54 20 63 6f 75 6e 74 28 2a 29 20 46 52 4f  ECT count(*) FRO
07f0: 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 7d  M sqlite_master}
0800: 0a 73 65 74 20 70 61 67 65 53 69 7a 65 20 5b 65  .set pageSize [e
0810: 78 70 72 20 7b 77 69 64 65 28 5b 64 62 20 6f 6e  xpr {wide([db on
0820: 65 20 7b 50 52 41 47 4d 41 20 70 61 67 65 5f 73  e {PRAGMA page_s
0830: 69 7a 65 7d 5d 29 7d 5d 0a 0a 69 66 20 7b 24 66  ize}])}]..if {$f
0840: 6c 61 67 73 28 2d 70 61 67 65 69 6e 66 6f 29 7d  lags(-pageinfo)}
0850: 20 7b 0a 20 20 64 62 20 65 76 61 6c 20 7b 43 52   {.  db eval {CR
0860: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42  EATE VIRTUAL TAB
0870: 4c 45 20 74 65 6d 70 2e 73 74 61 74 20 55 53 49  LE temp.stat USI
0880: 4e 47 20 64 62 73 74 61 74 7d 0a 20 20 64 62 20  NG dbstat}.  db 
0890: 65 76 61 6c 20 7b 53 45 4c 45 43 54 20 6e 61 6d  eval {SELECT nam
08a0: 65 2c 20 70 61 74 68 2c 20 70 61 67 65 6e 6f 20  e, path, pageno 
08b0: 46 52 4f 4d 20 74 65 6d 70 2e 73 74 61 74 20 4f  FROM temp.stat O
08c0: 52 44 45 52 20 42 59 20 70 61 67 65 6e 6f 7d 20  RDER BY pageno} 
08d0: 7b 0a 20 20 20 20 70 75 74 73 20 22 24 70 61 67  {.    puts "$pag
08e0: 65 6e 6f 20 24 6e 61 6d 65 20 24 70 61 74 68 22  eno $name $path"
08f0: 0a 20 20 7d 0a 20 20 65 78 69 74 20 30 0a 7d 0a  .  }.  exit 0.}.
0900: 69 66 20 7b 24 66 6c 61 67 73 28 2d 73 74 61 74  if {$flags(-stat
0910: 73 29 7d 20 7b 0a 20 20 64 62 20 65 76 61 6c 20  s)} {.  db eval 
0920: 7b 43 52 45 41 54 45 20 56 49 52 54 55 41 4c 20  {CREATE VIRTUAL 
0930: 54 41 42 4c 45 20 74 65 6d 70 2e 73 74 61 74 20  TABLE temp.stat 
0940: 55 53 49 4e 47 20 64 62 73 74 61 74 7d 0a 20 20  USING dbstat}.  
0950: 70 75 74 73 20 22 42 45 47 49 4e 3b 22 0a 20 20  puts "BEGIN;".  
0960: 70 75 74 73 20 22 43 52 45 41 54 45 20 54 41 42  puts "CREATE TAB
0970: 4c 45 20 73 74 61 74 73 28 22 0a 20 20 70 75 74  LE stats(".  put
0980: 73 20 22 20 20 6e 61 6d 65 20 20 20 20 20 20 20  s "  name       
0990: 53 54 52 49 4e 47 2c 20 20 20 20 20 20 20 20 20  STRING,         
09a0: 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 61 62    /* Name of tab
09b0: 6c 65 20 6f 72 20 69 6e 64 65 78 20 2a 2f 22 0a  le or index */".
09c0: 20 20 70 75 74 73 20 22 20 20 70 61 74 68 20 20    puts "  path  
09d0: 20 20 20 20 20 49 4e 54 45 47 45 52 2c 20 20 20       INTEGER,   
09e0: 20 20 20 20 20 20 20 2f 2a 20 50 61 74 68 20 74         /* Path t
09f0: 6f 20 70 61 67 65 20 66 72 6f 6d 20 72 6f 6f 74  o page from root
0a00: 20 2a 2f 22 0a 20 20 70 75 74 73 20 22 20 20 70   */".  puts "  p
0a10: 61 67 65 6e 6f 20 20 20 20 20 49 4e 54 45 47 45  ageno     INTEGE
0a20: 52 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50  R,          /* P
0a30: 61 67 65 20 6e 75 6d 62 65 72 20 2a 2f 22 0a 20  age number */". 
0a40: 20 70 75 74 73 20 22 20 20 70 61 67 65 74 79 70   puts "  pagetyp
0a50: 65 20 20 20 53 54 52 49 4e 47 2c 20 20 20 20 20  e   STRING,     
0a60: 20 20 20 20 20 20 2f 2a 20 27 69 6e 74 65 72 6e        /* 'intern
0a70: 61 6c 27 2c 20 27 6c 65 61 66 27 20 6f 72 20 27  al', 'leaf' or '
0a80: 6f 76 65 72 66 6c 6f 77 27 20 2a 2f 22 0a 20 20  overflow' */".  
0a90: 70 75 74 73 20 22 20 20 6e 63 65 6c 6c 20 20 20  puts "  ncell   
0aa0: 20 20 20 49 4e 54 45 47 45 52 2c 20 20 20 20 20     INTEGER,     
0ab0: 20 20 20 20 20 2f 2a 20 43 65 6c 6c 73 20 6f 6e       /* Cells on
0ac0: 20 70 61 67 65 20 28 30 20 66 6f 72 20 6f 76 65   page (0 for ove
0ad0: 72 66 6c 6f 77 29 20 2a 2f 22 0a 20 20 70 75 74  rflow) */".  put
0ae0: 73 20 22 20 20 70 61 79 6c 6f 61 64 20 20 20 20  s "  payload    
0af0: 49 4e 54 45 47 45 52 2c 20 20 20 20 20 20 20 20  INTEGER,        
0b00: 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 70 61    /* Bytes of pa
0b10: 79 6c 6f 61 64 20 6f 6e 20 74 68 69 73 20 70 61  yload on this pa
0b20: 67 65 20 2a 2f 22 0a 20 20 70 75 74 73 20 22 20  ge */".  puts " 
0b30: 20 75 6e 75 73 65 64 20 20 20 20 20 49 4e 54 45   unused     INTE
0b40: 47 45 52 2c 20 20 20 20 20 20 20 20 20 20 2f 2a  GER,          /*
0b50: 20 42 79 74 65 73 20 6f 66 20 75 6e 75 73 65 64   Bytes of unused
0b60: 20 73 70 61 63 65 20 6f 6e 20 74 68 69 73 20 70   space on this p
0b70: 61 67 65 20 2a 2f 22 0a 20 20 70 75 74 73 20 22  age */".  puts "
0b80: 20 20 6d 78 5f 70 61 79 6c 6f 61 64 20 49 4e 54    mx_payload INT
0b90: 45 47 45 52 2c 20 20 20 20 20 20 20 20 20 20 2f  EGER,          /
0ba0: 2a 20 4c 61 72 67 65 73 74 20 70 61 79 6c 6f 61  * Largest payloa
0bb0: 64 20 73 69 7a 65 20 6f 66 20 61 6c 6c 20 63 65  d size of all ce
0bc0: 6c 6c 73 20 2a 2f 22 0a 20 20 70 75 74 73 20 22  lls */".  puts "
0bd0: 20 20 70 67 6f 66 66 73 65 74 20 20 20 49 4e 54    pgoffset   INT
0be0: 45 47 45 52 2c 20 20 20 20 20 20 20 20 20 20 2f  EGER,          /
0bf0: 2a 20 4f 66 66 73 65 74 20 6f 66 20 70 61 67 65  * Offset of page
0c00: 20 69 6e 20 66 69 6c 65 20 2a 2f 22 0a 20 20 70   in file */".  p
0c10: 75 74 73 20 22 20 20 70 67 73 69 7a 65 20 20 20  uts "  pgsize   
0c20: 20 20 49 4e 54 45 47 45 52 20 20 20 20 20 20 20    INTEGER       
0c30: 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 74      /* Size of t
0c40: 68 65 20 70 61 67 65 20 2a 2f 22 0a 20 20 70 75  he page */".  pu
0c50: 74 73 20 22 29 3b 22 0a 20 20 64 62 20 65 76 61  ts ");".  db eva
0c60: 6c 20 7b 53 45 4c 45 43 54 20 71 75 6f 74 65 28  l {SELECT quote(
0c70: 6e 61 6d 65 29 20 7c 7c 20 27 2c 27 20 7c 7c 0a  name) || ',' ||.
0c80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c90: 20 20 71 75 6f 74 65 28 70 61 74 68 29 20 7c 7c    quote(path) ||
0ca0: 20 27 2c 27 20 7c 7c 0a 20 20 20 20 20 20 20 20   ',' ||.        
0cb0: 20 20 20 20 20 20 20 20 20 20 71 75 6f 74 65 28            quote(
0cc0: 70 61 67 65 6e 6f 29 20 7c 7c 20 27 2c 27 20 7c  pageno) || ',' |
0cd0: 7c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  |.              
0ce0: 20 20 20 20 71 75 6f 74 65 28 70 61 67 65 74 79      quote(pagety
0cf0: 70 65 29 20 7c 7c 20 27 2c 27 20 7c 7c 0a 20 20  pe) || ',' ||.  
0d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0d10: 71 75 6f 74 65 28 6e 63 65 6c 6c 29 20 7c 7c 20  quote(ncell) || 
0d20: 27 2c 27 20 7c 7c 0a 20 20 20 20 20 20 20 20 20  ',' ||.         
0d30: 20 20 20 20 20 20 20 20 20 71 75 6f 74 65 28 70           quote(p
0d40: 61 79 6c 6f 61 64 29 20 7c 7c 20 27 2c 27 20 7c  ayload) || ',' |
0d50: 7c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  |.              
0d60: 20 20 20 20 71 75 6f 74 65 28 75 6e 75 73 65 64      quote(unused
0d70: 29 20 7c 7c 20 27 2c 27 20 7c 7c 0a 20 20 20 20  ) || ',' ||.    
0d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 71 75                qu
0d90: 6f 74 65 28 6d 78 5f 70 61 79 6c 6f 61 64 29 20  ote(mx_payload) 
0da0: 7c 7c 20 27 2c 27 20 7c 7c 0a 20 20 20 20 20 20  || ',' ||.      
0db0: 20 20 20 20 20 20 20 20 20 20 20 20 71 75 6f 74              quot
0dc0: 65 28 70 67 6f 66 66 73 65 74 29 20 7c 7c 20 27  e(pgoffset) || '
0dd0: 2c 27 20 7c 7c 0a 20 20 20 20 20 20 20 20 20 20  ,' ||.          
0de0: 20 20 20 20 20 20 20 20 71 75 6f 74 65 28 70 67          quote(pg
0df0: 73 69 7a 65 29 20 41 53 20 78 20 46 52 4f 4d 20  size) AS x FROM 
0e00: 73 74 61 74 7d 20 7b 0a 20 20 20 20 70 75 74 73  stat} {.    puts
0e10: 20 22 49 4e 53 45 52 54 20 49 4e 54 4f 20 73 74   "INSERT INTO st
0e20: 61 74 73 20 56 41 4c 55 45 53 28 24 78 29 3b 22  ats VALUES($x);"
0e30: 0a 20 20 7d 0a 20 20 70 75 74 73 20 22 43 4f 4d  .  }.  puts "COM
0e40: 4d 49 54 3b 22 0a 20 20 65 78 69 74 20 30 0a 7d  MIT;".  exit 0.}
0e50: 0a 0a 23 20 49 6e 2d 6d 65 6d 6f 72 79 20 64 61  ..# In-memory da
0e60: 74 61 62 61 73 65 20 66 6f 72 20 63 6f 6c 6c 65  tabase for colle
0e70: 63 74 69 6e 67 20 73 74 61 74 69 73 74 69 63 73  cting statistics
0e80: 2e 20 54 68 69 73 20 73 63 72 69 70 74 20 6c 6f  . This script lo
0e90: 6f 70 73 20 74 68 72 6f 75 67 68 0a 23 20 74 68  ops through.# th
0ea0: 65 20 74 61 62 6c 65 73 20 61 6e 64 20 69 6e 64  e tables and ind
0eb0: 69 63 65 73 20 69 6e 20 74 68 65 20 64 61 74 61  ices in the data
0ec0: 62 61 73 65 20 62 65 69 6e 67 20 61 6e 61 6c 79  base being analy
0ed0: 7a 65 64 2c 20 61 64 64 69 6e 67 20 61 20 72 6f  zed, adding a ro
0ee0: 77 20 66 6f 72 20 65 61 63 68 0a 23 20 74 6f 20  w for each.# to 
0ef0: 61 6e 20 69 6e 2d 6d 65 6d 6f 72 79 20 64 61 74  an in-memory dat
0f00: 61 62 61 73 65 20 28 66 6f 72 20 77 68 69 63 68  abase (for which
0f10: 20 74 68 65 20 73 63 68 65 6d 61 20 69 73 20 73   the schema is s
0f20: 68 6f 77 6e 20 62 65 6c 6f 77 29 2e 20 49 74 20  hown below). It 
0f30: 74 68 65 6e 0a 23 20 71 75 65 72 69 65 73 20 74  then.# queries t
0f40: 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 64 62 20  he in-memory db 
0f50: 74 6f 20 70 72 6f 64 75 63 65 20 74 68 65 20 73  to produce the s
0f60: 70 61 63 65 2d 61 6e 61 6c 79 73 69 73 20 72 65  pace-analysis re
0f70: 70 6f 72 74 2e 0a 23 0a 73 71 6c 69 74 65 33 20  port..#.sqlite3 
0f80: 6d 65 6d 20 3a 6d 65 6d 6f 72 79 3a 0a 73 65 74  mem :memory:.set
0f90: 20 74 61 62 6c 65 64 65 66 20 7b 43 52 45 41 54   tabledef {CREAT
0fa0: 45 20 54 41 42 4c 45 20 73 70 61 63 65 5f 75 73  E TABLE space_us
0fb0: 65 64 28 0a 20 20 20 6e 61 6d 65 20 63 6c 6f 62  ed(.   name clob
0fc0: 2c 20 20 20 20 20 20 20 20 2d 2d 20 4e 61 6d 65  ,        -- Name
0fd0: 20 6f 66 20 61 20 74 61 62 6c 65 20 6f 72 20 69   of a table or i
0fe0: 6e 64 65 78 20 69 6e 20 74 68 65 20 64 61 74 61  ndex in the data
0ff0: 62 61 73 65 20 66 69 6c 65 0a 20 20 20 74 62 6c  base file.   tbl
1000: 6e 61 6d 65 20 63 6c 6f 62 2c 20 20 20 20 20 2d  name clob,     -
1010: 2d 20 4e 61 6d 65 20 6f 66 20 61 73 73 6f 63 69  - Name of associ
1020: 61 74 65 64 20 74 61 62 6c 65 0a 20 20 20 69 73  ated table.   is
1030: 5f 69 6e 64 65 78 20 62 6f 6f 6c 65 61 6e 2c 20  _index boolean, 
1040: 2d 2d 20 54 52 55 45 20 69 66 20 69 74 20 69 73  -- TRUE if it is
1050: 20 61 6e 20 69 6e 64 65 78 2c 20 66 61 6c 73 65   an index, false
1060: 20 66 6f 72 20 61 20 74 61 62 6c 65 0a 20 20 20   for a table.   
1070: 6e 65 6e 74 72 79 20 69 6e 74 2c 20 20 20 20 20  nentry int,     
1080: 20 20 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20 65    -- Number of e
1090: 6e 74 72 69 65 73 20 69 6e 20 74 68 65 20 42 54  ntries in the BT
10a0: 72 65 65 0a 20 20 20 6c 65 61 66 5f 65 6e 74 72  ree.   leaf_entr
10b0: 69 65 73 20 69 6e 74 2c 20 2d 2d 20 4e 75 6d 62  ies int, -- Numb
10c0: 65 72 20 6f 66 20 6c 65 61 66 20 65 6e 74 72 69  er of leaf entri
10d0: 65 73 0a 20 20 20 70 61 79 6c 6f 61 64 20 69 6e  es.   payload in
10e0: 74 2c 20 20 20 20 20 20 2d 2d 20 54 6f 74 61 6c  t,      -- Total
10f0: 20 61 6d 6f 75 6e 74 20 6f 66 20 64 61 74 61 20   amount of data 
1100: 73 74 6f 72 65 64 20 69 6e 20 74 68 69 73 20 74  stored in this t
1110: 61 62 6c 65 20 6f 72 20 69 6e 64 65 78 0a 20 20  able or index.  
1120: 20 6f 76 66 6c 5f 70 61 79 6c 6f 61 64 20 69 6e   ovfl_payload in
1130: 74 2c 20 2d 2d 20 54 6f 74 61 6c 20 61 6d 6f 75  t, -- Total amou
1140: 6e 74 20 6f 66 20 64 61 74 61 20 73 74 6f 72 65  nt of data store
1150: 64 20 6f 6e 20 6f 76 65 72 66 6c 6f 77 20 70 61  d on overflow pa
1160: 67 65 73 0a 20 20 20 6f 76 66 6c 5f 63 6e 74 20  ges.   ovfl_cnt 
1170: 69 6e 74 2c 20 20 20 20 20 2d 2d 20 4e 75 6d 62  int,     -- Numb
1180: 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20 74 68  er of entries th
1190: 61 74 20 75 73 65 20 6f 76 65 72 66 6c 6f 77 0a  at use overflow.
11a0: 20 20 20 6d 78 5f 70 61 79 6c 6f 61 64 20 69 6e     mx_payload in
11b0: 74 2c 20 20 20 2d 2d 20 4d 61 78 69 6d 75 6d 20  t,   -- Maximum 
11c0: 70 61 79 6c 6f 61 64 20 73 69 7a 65 0a 20 20 20  payload size.   
11d0: 69 6e 74 5f 70 61 67 65 73 20 69 6e 74 2c 20 20  int_pages int,  
11e0: 20 20 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20 69    -- Number of i
11f0: 6e 74 65 72 69 6f 72 20 70 61 67 65 73 20 75 73  nterior pages us
1200: 65 64 0a 20 20 20 6c 65 61 66 5f 70 61 67 65 73  ed.   leaf_pages
1210: 20 69 6e 74 2c 20 20 20 2d 2d 20 4e 75 6d 62 65   int,   -- Numbe
1220: 72 20 6f 66 20 6c 65 61 66 20 70 61 67 65 73 20  r of leaf pages 
1230: 75 73 65 64 0a 20 20 20 6f 76 66 6c 5f 70 61 67  used.   ovfl_pag
1240: 65 73 20 69 6e 74 2c 20 20 20 2d 2d 20 4e 75 6d  es int,   -- Num
1250: 62 65 72 20 6f 66 20 6f 76 65 72 66 6c 6f 77 20  ber of overflow 
1260: 70 61 67 65 73 20 75 73 65 64 0a 20 20 20 69 6e  pages used.   in
1270: 74 5f 75 6e 75 73 65 64 20 69 6e 74 2c 20 20 20  t_unused int,   
1280: 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20 75 6e 75  -- Number of unu
1290: 73 65 64 20 62 79 74 65 73 20 6f 6e 20 69 6e 74  sed bytes on int
12a0: 65 72 69 6f 72 20 70 61 67 65 73 0a 20 20 20 6c  erior pages.   l
12b0: 65 61 66 5f 75 6e 75 73 65 64 20 69 6e 74 2c 20  eaf_unused int, 
12c0: 20 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20 75 6e   -- Number of un
12d0: 75 73 65 64 20 62 79 74 65 73 20 6f 6e 20 70 72  used bytes on pr
12e0: 69 6d 61 72 79 20 70 61 67 65 73 0a 20 20 20 6f  imary pages.   o
12f0: 76 66 6c 5f 75 6e 75 73 65 64 20 69 6e 74 2c 20  vfl_unused int, 
1300: 20 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20 75 6e   -- Number of un
1310: 75 73 65 64 20 62 79 74 65 73 20 6f 6e 20 6f 76  used bytes on ov
1320: 65 72 66 6c 6f 77 20 70 61 67 65 73 0a 20 20 20  erflow pages.   
1330: 67 61 70 5f 63 6e 74 20 69 6e 74 2c 20 20 20 20  gap_cnt int,    
1340: 20 20 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20 67    -- Number of g
1350: 61 70 73 20 69 6e 20 74 68 65 20 70 61 67 65 20  aps in the page 
1360: 6c 61 79 6f 75 74 0a 20 20 20 63 6f 6d 70 72 65  layout.   compre
1370: 73 73 65 64 5f 73 69 7a 65 20 69 6e 74 20 20 2d  ssed_size int  -
1380: 2d 20 54 6f 74 61 6c 20 62 79 74 65 73 20 73 74  - Total bytes st
1390: 6f 72 65 64 20 6f 6e 20 64 69 73 6b 0a 29 3b 7d  ored on disk.);}
13a0: 0a 6d 65 6d 20 65 76 61 6c 20 24 74 61 62 6c 65  .mem eval $table
13b0: 64 65 66 0a 0a 23 20 43 72 65 61 74 65 20 61 20  def..# Create a 
13c0: 74 65 6d 70 6f 72 61 72 79 20 22 64 62 73 74 61  temporary "dbsta
13d0: 74 22 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  t" virtual table
13e0: 2e 0a 23 0a 64 62 20 65 76 61 6c 20 7b 43 52 45  ..#.db eval {CRE
13f0: 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c  ATE VIRTUAL TABL
1400: 45 20 74 65 6d 70 2e 73 74 61 74 20 55 53 49 4e  E temp.stat USIN
1410: 47 20 64 62 73 74 61 74 7d 0a 64 62 20 65 76 61  G dbstat}.db eva
1420: 6c 20 7b 43 52 45 41 54 45 20 54 45 4d 50 20 54  l {CREATE TEMP T
1430: 41 42 4c 45 20 64 62 73 74 61 74 20 41 53 20 53  ABLE dbstat AS S
1440: 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 74 65 6d  ELECT * FROM tem
1450: 70 2e 73 74 61 74 0a 20 20 20 20 20 20 20 20 20  p.stat.         
1460: 4f 52 44 45 52 20 42 59 20 6e 61 6d 65 2c 20 70  ORDER BY name, p
1470: 61 74 68 7d 0a 64 62 20 65 76 61 6c 20 7b 44 52  ath}.db eval {DR
1480: 4f 50 20 54 41 42 4c 45 20 74 65 6d 70 2e 73 74  OP TABLE temp.st
1490: 61 74 7d 0a 0a 70 72 6f 63 20 69 73 6c 65 61 66  at}..proc isleaf
14a0: 20 7b 70 61 67 65 74 79 70 65 20 69 73 5f 69 6e   {pagetype is_in
14b0: 64 65 78 7d 20 7b 0a 20 20 72 65 74 75 72 6e 20  dex} {.  return 
14c0: 5b 65 78 70 72 20 7b 24 70 61 67 65 74 79 70 65  [expr {$pagetype
14d0: 20 3d 3d 20 22 6c 65 61 66 22 20 7c 7c 20 28 24   == "leaf" || ($
14e0: 70 61 67 65 74 79 70 65 20 3d 3d 20 22 69 6e 74  pagetype == "int
14f0: 65 72 6e 61 6c 22 20 26 26 20 24 69 73 5f 69 6e  ernal" && $is_in
1500: 64 65 78 29 7d 5d 0a 7d 0a 70 72 6f 63 20 69 73  dex)}].}.proc is
1510: 6f 76 65 72 66 6c 6f 77 20 7b 70 61 67 65 74 79  overflow {pagety
1520: 70 65 20 69 73 5f 69 6e 64 65 78 7d 20 7b 0a 20  pe is_index} {. 
1530: 20 72 65 74 75 72 6e 20 5b 65 78 70 72 20 7b 24   return [expr {$
1540: 70 61 67 65 74 79 70 65 20 3d 3d 20 22 6f 76 65  pagetype == "ove
1550: 72 66 6c 6f 77 22 7d 5d 0a 7d 0a 70 72 6f 63 20  rflow"}].}.proc 
1560: 69 73 69 6e 74 65 72 6e 61 6c 20 7b 70 61 67 65  isinternal {page
1570: 74 79 70 65 20 69 73 5f 69 6e 64 65 78 7d 20 7b  type is_index} {
1580: 0a 20 20 72 65 74 75 72 6e 20 5b 65 78 70 72 20  .  return [expr 
1590: 7b 24 70 61 67 65 74 79 70 65 20 3d 3d 20 22 69  {$pagetype == "i
15a0: 6e 74 65 72 6e 61 6c 22 20 26 26 20 24 69 73 5f  nternal" && $is_
15b0: 69 6e 64 65 78 3d 3d 30 7d 5d 0a 7d 0a 0a 64 62  index==0}].}..db
15c0: 20 66 75 6e 63 20 69 73 6c 65 61 66 20 69 73 6c   func isleaf isl
15d0: 65 61 66 0a 64 62 20 66 75 6e 63 20 69 73 69 6e  eaf.db func isin
15e0: 74 65 72 6e 61 6c 20 69 73 69 6e 74 65 72 6e 61  ternal isinterna
15f0: 6c 0a 64 62 20 66 75 6e 63 20 69 73 6f 76 65 72  l.db func isover
1600: 66 6c 6f 77 20 69 73 6f 76 65 72 66 6c 6f 77 0a  flow isoverflow.
1610: 0a 73 65 74 20 69 73 43 6f 6d 70 72 65 73 73 65  .set isCompresse
1620: 64 20 30 0a 73 65 74 20 63 6f 6d 70 72 65 73 73  d 0.set compress
1630: 4f 76 65 72 68 65 61 64 20 30 0a 73 65 74 20 73  Overhead 0.set s
1640: 71 6c 20 7b 20 53 45 4c 45 43 54 20 6e 61 6d 65  ql { SELECT name
1650: 2c 20 74 62 6c 5f 6e 61 6d 65 20 46 52 4f 4d 20  , tbl_name FROM 
1660: 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48  sqlite_master WH
1670: 45 52 45 20 72 6f 6f 74 70 61 67 65 3e 30 20 7d  ERE rootpage>0 }
1680: 0a 66 6f 72 65 61 63 68 20 7b 6e 61 6d 65 20 74  .foreach {name t
1690: 62 6c 6e 61 6d 65 7d 20 5b 63 6f 6e 63 61 74 20  blname} [concat 
16a0: 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 73 71  sqlite_master sq
16b0: 6c 69 74 65 5f 6d 61 73 74 65 72 20 5b 64 62 20  lite_master [db 
16c0: 65 76 61 6c 20 24 73 71 6c 5d 5d 20 7b 0a 0a 20  eval $sql]] {.. 
16d0: 20 73 65 74 20 69 73 5f 69 6e 64 65 78 20 5b 65   set is_index [e
16e0: 78 70 72 20 7b 24 6e 61 6d 65 21 3d 24 74 62 6c  xpr {$name!=$tbl
16f0: 6e 61 6d 65 7d 5d 0a 20 20 64 62 20 65 76 61 6c  name}].  db eval
1700: 20 7b 0a 20 20 20 20 53 45 4c 45 43 54 20 0a 20   {.    SELECT . 
1710: 20 20 20 20 20 73 75 6d 28 6e 63 65 6c 6c 29 20       sum(ncell) 
1720: 41 53 20 6e 65 6e 74 72 79 2c 0a 20 20 20 20 20  AS nentry,.     
1730: 20 73 75 6d 28 69 73 6c 65 61 66 28 70 61 67 65   sum(isleaf(page
1740: 74 79 70 65 2c 20 24 69 73 5f 69 6e 64 65 78 29  type, $is_index)
1750: 20 2a 20 6e 63 65 6c 6c 29 20 41 53 20 6c 65 61   * ncell) AS lea
1760: 66 5f 65 6e 74 72 69 65 73 2c 0a 20 20 20 20 20  f_entries,.     
1770: 20 73 75 6d 28 70 61 79 6c 6f 61 64 29 20 41 53   sum(payload) AS
1780: 20 70 61 79 6c 6f 61 64 2c 0a 20 20 20 20 20 20   payload,.      
1790: 73 75 6d 28 69 73 6f 76 65 72 66 6c 6f 77 28 70  sum(isoverflow(p
17a0: 61 67 65 74 79 70 65 2c 20 24 69 73 5f 69 6e 64  agetype, $is_ind
17b0: 65 78 29 20 2a 20 70 61 79 6c 6f 61 64 29 20 41  ex) * payload) A
17c0: 53 20 6f 76 66 6c 5f 70 61 79 6c 6f 61 64 2c 0a  S ovfl_payload,.
17d0: 20 20 20 20 20 20 73 75 6d 28 70 61 74 68 20 4c        sum(path L
17e0: 49 4b 45 20 27 25 2b 30 30 30 30 30 30 27 29 20  IKE '%+000000') 
17f0: 41 53 20 6f 76 66 6c 5f 63 6e 74 2c 0a 20 20 20  AS ovfl_cnt,.   
1800: 20 20 20 6d 61 78 28 6d 78 5f 70 61 79 6c 6f 61     max(mx_payloa
1810: 64 29 20 41 53 20 6d 78 5f 70 61 79 6c 6f 61 64  d) AS mx_payload
1820: 2c 0a 20 20 20 20 20 20 73 75 6d 28 69 73 69 6e  ,.      sum(isin
1830: 74 65 72 6e 61 6c 28 70 61 67 65 74 79 70 65 2c  ternal(pagetype,
1840: 20 24 69 73 5f 69 6e 64 65 78 29 29 20 41 53 20   $is_index)) AS 
1850: 69 6e 74 5f 70 61 67 65 73 2c 0a 20 20 20 20 20  int_pages,.     
1860: 20 73 75 6d 28 69 73 6c 65 61 66 28 70 61 67 65   sum(isleaf(page
1870: 74 79 70 65 2c 20 24 69 73 5f 69 6e 64 65 78 29  type, $is_index)
1880: 29 20 41 53 20 6c 65 61 66 5f 70 61 67 65 73 2c  ) AS leaf_pages,
1890: 0a 20 20 20 20 20 20 73 75 6d 28 69 73 6f 76 65  .      sum(isove
18a0: 72 66 6c 6f 77 28 70 61 67 65 74 79 70 65 2c 20  rflow(pagetype, 
18b0: 24 69 73 5f 69 6e 64 65 78 29 29 20 41 53 20 6f  $is_index)) AS o
18c0: 76 66 6c 5f 70 61 67 65 73 2c 0a 20 20 20 20 20  vfl_pages,.     
18d0: 20 73 75 6d 28 69 73 69 6e 74 65 72 6e 61 6c 28   sum(isinternal(
18e0: 70 61 67 65 74 79 70 65 2c 20 24 69 73 5f 69 6e  pagetype, $is_in
18f0: 64 65 78 29 20 2a 20 75 6e 75 73 65 64 29 20 41  dex) * unused) A
1900: 53 20 69 6e 74 5f 75 6e 75 73 65 64 2c 0a 20 20  S int_unused,.  
1910: 20 20 20 20 73 75 6d 28 69 73 6c 65 61 66 28 70      sum(isleaf(p
1920: 61 67 65 74 79 70 65 2c 20 24 69 73 5f 69 6e 64  agetype, $is_ind
1930: 65 78 29 20 2a 20 75 6e 75 73 65 64 29 20 41 53  ex) * unused) AS
1940: 20 6c 65 61 66 5f 75 6e 75 73 65 64 2c 0a 20 20   leaf_unused,.  
1950: 20 20 20 20 73 75 6d 28 69 73 6f 76 65 72 66 6c      sum(isoverfl
1960: 6f 77 28 70 61 67 65 74 79 70 65 2c 20 24 69 73  ow(pagetype, $is
1970: 5f 69 6e 64 65 78 29 20 2a 20 75 6e 75 73 65 64  _index) * unused
1980: 29 20 41 53 20 6f 76 66 6c 5f 75 6e 75 73 65 64  ) AS ovfl_unused
1990: 2c 0a 20 20 20 20 20 20 73 75 6d 28 70 67 73 69  ,.      sum(pgsi
19a0: 7a 65 29 20 41 53 20 63 6f 6d 70 72 65 73 73 65  ze) AS compresse
19b0: 64 5f 73 69 7a 65 0a 20 20 20 20 46 52 4f 4d 20  d_size.    FROM 
19c0: 74 65 6d 70 2e 64 62 73 74 61 74 20 57 48 45 52  temp.dbstat WHER
19d0: 45 20 6e 61 6d 65 20 3d 20 24 6e 61 6d 65 0a 20  E name = $name. 
19e0: 20 7d 20 62 72 65 61 6b 0a 0a 20 20 73 65 74 20   } break..  set 
19f0: 74 6f 74 61 6c 5f 70 61 67 65 73 20 5b 65 78 70  total_pages [exp
1a00: 72 20 7b 24 6c 65 61 66 5f 70 61 67 65 73 2b 24  r {$leaf_pages+$
1a10: 69 6e 74 5f 70 61 67 65 73 2b 24 6f 76 66 6c 5f  int_pages+$ovfl_
1a20: 70 61 67 65 73 7d 5d 0a 20 20 73 65 74 20 73 74  pages}].  set st
1a30: 6f 72 61 67 65 20 5b 65 78 70 72 20 7b 24 74 6f  orage [expr {$to
1a40: 74 61 6c 5f 70 61 67 65 73 2a 24 70 61 67 65 53  tal_pages*$pageS
1a50: 69 7a 65 7d 5d 0a 20 20 69 66 20 7b 21 24 69 73  ize}].  if {!$is
1a60: 43 6f 6d 70 72 65 73 73 65 64 20 26 26 20 24 73  Compressed && $s
1a70: 74 6f 72 61 67 65 3e 24 63 6f 6d 70 72 65 73 73  torage>$compress
1a80: 65 64 5f 73 69 7a 65 7d 20 7b 0a 20 20 20 20 73  ed_size} {.    s
1a90: 65 74 20 69 73 43 6f 6d 70 72 65 73 73 65 64 20  et isCompressed 
1aa0: 31 0a 20 20 20 20 73 65 74 20 63 6f 6d 70 72 65  1.    set compre
1ab0: 73 73 4f 76 65 72 68 65 61 64 20 31 34 0a 20 20  ssOverhead 14.  
1ac0: 7d 0a 0a 20 20 23 20 43 6f 6c 75 6d 6e 20 27 67  }..  # Column 'g
1ad0: 61 70 5f 63 6e 74 27 20 69 73 20 73 65 74 20 74  ap_cnt' is set t
1ae0: 6f 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  o the number of 
1af0: 6e 6f 6e 2d 63 6f 6e 74 69 67 75 6f 75 73 20 65  non-contiguous e
1b00: 6e 74 72 69 65 73 20 69 6e 20 74 68 65 0a 20 20  ntries in the.  
1b10: 23 20 6c 69 73 74 20 6f 66 20 70 61 67 65 73 20  # list of pages 
1b20: 76 69 73 69 74 65 64 20 69 66 20 74 68 65 20 62  visited if the b
1b30: 2d 74 72 65 65 20 73 74 72 75 63 74 75 72 65 20  -tree structure 
1b40: 69 73 20 74 72 61 76 65 72 73 65 64 20 69 6e 20  is traversed in 
1b50: 61 20 74 6f 70 2d 64 6f 77 6e 0a 20 20 23 20 66  a top-down.  # f
1b60: 61 73 68 69 6f 6e 20 28 65 61 63 68 20 6e 6f 64  ashion (each nod
1b70: 65 20 76 69 73 69 74 65 64 20 62 65 66 6f 72 65  e visited before
1b80: 20 69 74 73 20 63 68 69 6c 64 2d 74 72 65 65 20   its child-tree 
1b90: 69 73 20 70 61 73 73 65 64 29 2e 20 41 6e 79 20  is passed). Any 
1ba0: 6f 76 65 72 66 6c 6f 77 0a 20 20 23 20 63 68 61  overflow.  # cha
1bb0: 69 6e 73 20 70 72 65 73 65 6e 74 20 61 72 65 20  ins present are 
1bc0: 74 72 61 76 65 72 73 65 64 20 66 72 6f 6d 20 73  traversed from s
1bd0: 74 61 72 74 20 74 6f 20 66 69 6e 69 73 68 20 62  tart to finish b
1be0: 65 66 6f 72 65 20 61 6e 79 20 63 68 69 6c 64 2d  efore any child-
1bf0: 74 72 65 65 0a 20 20 23 20 69 73 2e 0a 20 20 23  tree.  # is..  #
1c00: 0a 20 20 73 65 74 20 67 61 70 5f 63 6e 74 20 30  .  set gap_cnt 0
1c10: 0a 20 20 73 65 74 20 70 72 65 76 20 30 0a 20 20  .  set prev 0.  
1c20: 64 62 20 65 76 61 6c 20 7b 0a 20 20 20 20 53 45  db eval {.    SE
1c30: 4c 45 43 54 20 70 61 67 65 6e 6f 2c 20 70 61 67  LECT pageno, pag
1c40: 65 74 79 70 65 20 46 52 4f 4d 20 74 65 6d 70 2e  etype FROM temp.
1c50: 64 62 73 74 61 74 0a 20 20 20 20 20 57 48 45 52  dbstat.     WHER
1c60: 45 20 6e 61 6d 65 3d 24 6e 61 6d 65 0a 20 20 20  E name=$name.   
1c70: 20 20 4f 52 44 45 52 20 42 59 20 70 61 67 65 6e    ORDER BY pagen
1c80: 6f 0a 20 20 7d 20 7b 0a 20 20 20 20 69 66 20 7b  o.  } {.    if {
1c90: 24 70 72 65 76 3e 30 20 26 26 20 24 70 61 67 65  $prev>0 && $page
1ca0: 74 79 70 65 3d 3d 22 6c 65 61 66 22 20 26 26 20  type=="leaf" && 
1cb0: 24 70 61 67 65 6e 6f 21 3d 24 70 72 65 76 2b 31  $pageno!=$prev+1
1cc0: 7d 20 7b 0a 20 20 20 20 20 20 69 6e 63 72 20 67  } {.      incr g
1cd0: 61 70 5f 63 6e 74 0a 20 20 20 20 7d 0a 20 20 20  ap_cnt.    }.   
1ce0: 20 73 65 74 20 70 72 65 76 20 24 70 61 67 65 6e   set prev $pagen
1cf0: 6f 0a 20 20 7d 0a 20 20 6d 65 6d 20 65 76 61 6c  o.  }.  mem eval
1d00: 20 7b 0a 20 20 20 20 49 4e 53 45 52 54 20 49 4e   {.    INSERT IN
1d10: 54 4f 20 73 70 61 63 65 5f 75 73 65 64 20 56 41  TO space_used VA
1d20: 4c 55 45 53 28 0a 20 20 20 20 20 20 24 6e 61 6d  LUES(.      $nam
1d30: 65 2c 0a 20 20 20 20 20 20 24 74 62 6c 6e 61 6d  e,.      $tblnam
1d40: 65 2c 0a 20 20 20 20 20 20 24 69 73 5f 69 6e 64  e,.      $is_ind
1d50: 65 78 2c 0a 20 20 20 20 20 20 24 6e 65 6e 74 72  ex,.      $nentr
1d60: 79 2c 0a 20 20 20 20 20 20 24 6c 65 61 66 5f 65  y,.      $leaf_e
1d70: 6e 74 72 69 65 73 2c 0a 20 20 20 20 20 20 24 70  ntries,.      $p
1d80: 61 79 6c 6f 61 64 2c 20 20 20 20 20 0a 20 20 20  ayload,     .   
1d90: 20 20 20 24 6f 76 66 6c 5f 70 61 79 6c 6f 61 64     $ovfl_payload
1da0: 2c 0a 20 20 20 20 20 20 24 6f 76 66 6c 5f 63 6e  ,.      $ovfl_cn
1db0: 74 2c 20 20 20 0a 20 20 20 20 20 20 24 6d 78 5f  t,   .      $mx_
1dc0: 70 61 79 6c 6f 61 64 2c 0a 20 20 20 20 20 20 24  payload,.      $
1dd0: 69 6e 74 5f 70 61 67 65 73 2c 0a 20 20 20 20 20  int_pages,.     
1de0: 20 24 6c 65 61 66 5f 70 61 67 65 73 2c 20 20 0a   $leaf_pages,  .
1df0: 20 20 20 20 20 20 24 6f 76 66 6c 5f 70 61 67 65        $ovfl_page
1e00: 73 2c 20 0a 20 20 20 20 20 20 24 69 6e 74 5f 75  s, .      $int_u
1e10: 6e 75 73 65 64 2c 20 0a 20 20 20 20 20 20 24 6c  nused, .      $l
1e20: 65 61 66 5f 75 6e 75 73 65 64 2c 0a 20 20 20 20  eaf_unused,.    
1e30: 20 20 24 6f 76 66 6c 5f 75 6e 75 73 65 64 2c 0a    $ovfl_unused,.
1e40: 20 20 20 20 20 20 24 67 61 70 5f 63 6e 74 2c 0a        $gap_cnt,.
1e50: 20 20 20 20 20 20 24 63 6f 6d 70 72 65 73 73 65        $compresse
1e60: 64 5f 73 69 7a 65 0a 20 20 20 20 29 3b 0a 20 20  d_size.    );.  
1e70: 7d 0a 7d 0a 0a 70 72 6f 63 20 69 6e 74 65 67 65  }.}..proc intege
1e80: 72 69 66 79 20 7b 72 65 61 6c 7d 20 7b 0a 20 20  rify {real} {.  
1e90: 69 66 20 7b 5b 73 74 72 69 6e 67 20 69 73 20 64  if {[string is d
1ea0: 6f 75 62 6c 65 20 2d 73 74 72 69 63 74 20 24 72  ouble -strict $r
1eb0: 65 61 6c 5d 7d 20 7b 0a 20 20 20 20 72 65 74 75  eal]} {.    retu
1ec0: 72 6e 20 5b 65 78 70 72 20 7b 77 69 64 65 28 24  rn [expr {wide($
1ed0: 72 65 61 6c 29 7d 5d 0a 20 20 7d 20 65 6c 73 65  real)}].  } else
1ee0: 20 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 30 0a   {.    return 0.
1ef0: 20 20 7d 0a 7d 0a 6d 65 6d 20 66 75 6e 63 74 69    }.}.mem functi
1f00: 6f 6e 20 69 6e 74 20 69 6e 74 65 67 65 72 69 66  on int integerif
1f10: 79 0a 0a 23 20 51 75 6f 74 65 20 61 20 73 74 72  y..# Quote a str
1f20: 69 6e 67 20 66 6f 72 20 75 73 65 20 69 6e 20 61  ing for use in a
1f30: 6e 20 53 51 4c 20 71 75 65 72 79 2e 20 45 78 61  n SQL query. Exa
1f40: 6d 70 6c 65 73 3a 0a 23 0a 23 20 5b 71 75 6f 74  mples:.#.# [quot
1f50: 65 20 7b 68 65 6c 6c 6f 20 77 6f 72 6c 64 7d 5d  e {hello world}]
1f60: 20 20 20 3d 3d 20 7b 27 68 65 6c 6c 6f 20 77 6f     == {'hello wo
1f70: 72 6c 64 27 7d 0a 23 20 5b 71 75 6f 74 65 20 7b  rld'}.# [quote {
1f80: 68 65 6c 6c 6f 20 77 6f 72 6c 64 27 73 7d 5d 20  hello world's}] 
1f90: 3d 3d 20 7b 27 68 65 6c 6c 6f 20 77 6f 72 6c 64  == {'hello world
1fa0: 27 27 73 27 7d 0a 23 0a 70 72 6f 63 20 71 75 6f  ''s'}.#.proc quo
1fb0: 74 65 20 7b 74 78 74 7d 20 7b 0a 20 20 72 65 74  te {txt} {.  ret
1fc0: 75 72 6e 20 5b 73 74 72 69 6e 67 20 6d 61 70 20  urn [string map 
1fd0: 7b 27 20 27 27 7d 20 24 74 78 74 5d 0a 7d 0a 0a  {' ''} $txt].}..
1fe0: 23 20 4f 75 74 70 75 74 20 61 20 74 69 74 6c 65  # Output a title
1ff0: 20 6c 69 6e 65 0a 23 0a 70 72 6f 63 20 74 69 74   line.#.proc tit
2000: 6c 65 6c 69 6e 65 20 7b 74 69 74 6c 65 7d 20 7b  leline {title} {
2010: 0a 20 20 69 66 20 7b 24 74 69 74 6c 65 3d 3d 22  .  if {$title=="
2020: 22 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 5b 73  "} {.    puts [s
2030: 74 72 69 6e 67 20 72 65 70 65 61 74 20 2a 20 37  tring repeat * 7
2040: 39 5d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20  9].  } else {.  
2050: 20 20 73 65 74 20 6c 65 6e 20 5b 73 74 72 69 6e    set len [strin
2060: 67 20 6c 65 6e 67 74 68 20 24 74 69 74 6c 65 5d  g length $title]
2070: 0a 20 20 20 20 73 65 74 20 73 74 61 72 73 20 5b  .    set stars [
2080: 73 74 72 69 6e 67 20 72 65 70 65 61 74 20 2a 20  string repeat * 
2090: 5b 65 78 70 72 20 37 39 2d 24 6c 65 6e 2d 35 5d  [expr 79-$len-5]
20a0: 5d 0a 20 20 20 20 70 75 74 73 20 22 2a 2a 2a 20  ].    puts "*** 
20b0: 24 74 69 74 6c 65 20 24 73 74 61 72 73 22 0a 20  $title $stars". 
20c0: 20 7d 0a 7d 0a 0a 23 20 47 65 6e 65 72 61 74 65   }.}..# Generate
20d0: 20 61 20 73 69 6e 67 6c 65 20 6c 69 6e 65 20 6f   a single line o
20e0: 66 20 6f 75 74 70 75 74 20 69 6e 20 74 68 65 20  f output in the 
20f0: 73 74 61 74 69 73 74 69 63 73 20 73 65 63 74 69  statistics secti
2100: 6f 6e 20 6f 66 20 74 68 65 0a 23 20 72 65 70 6f  on of the.# repo
2110: 72 74 2e 0a 23 0a 70 72 6f 63 20 73 74 61 74 6c  rt..#.proc statl
2120: 69 6e 65 20 7b 74 69 74 6c 65 20 76 61 6c 75 65  ine {title value
2130: 20 7b 65 78 74 72 61 20 7b 7d 7d 7d 20 7b 0a 20   {extra {}}} {. 
2140: 20 73 65 74 20 6c 65 6e 20 5b 73 74 72 69 6e 67   set len [string
2150: 20 6c 65 6e 67 74 68 20 24 74 69 74 6c 65 5d 0a   length $title].
2160: 20 20 73 65 74 20 64 6f 74 73 20 5b 73 74 72 69    set dots [stri
2170: 6e 67 20 72 65 70 65 61 74 20 2e 20 5b 65 78 70  ng repeat . [exp
2180: 72 20 35 30 2d 24 6c 65 6e 5d 5d 0a 20 20 73 65  r 50-$len]].  se
2190: 74 20 6c 65 6e 20 5b 73 74 72 69 6e 67 20 6c 65  t len [string le
21a0: 6e 67 74 68 20 24 76 61 6c 75 65 5d 0a 20 20 73  ngth $value].  s
21b0: 65 74 20 73 70 32 20 5b 73 74 72 69 6e 67 20 72  et sp2 [string r
21c0: 61 6e 67 65 20 7b 20 20 20 20 20 20 20 20 20 20  ange {          
21d0: 7d 20 24 6c 65 6e 20 65 6e 64 5d 0a 20 20 69 66  } $len end].  if
21e0: 20 7b 24 65 78 74 72 61 20 6e 65 20 22 22 7d 20   {$extra ne ""} 
21f0: 7b 0a 20 20 20 20 73 65 74 20 65 78 74 72 61 20  {.    set extra 
2200: 22 20 24 65 78 74 72 61 22 0a 20 20 7d 0a 20 20  " $extra".  }.  
2210: 70 75 74 73 20 22 24 74 69 74 6c 65 24 64 6f 74  puts "$title$dot
2220: 73 20 24 76 61 6c 75 65 24 73 70 32 24 65 78 74  s $value$sp2$ext
2230: 72 61 22 0a 7d 0a 0a 23 20 47 65 6e 65 72 61 74  ra".}..# Generat
2240: 65 20 61 20 66 6f 72 6d 61 74 74 65 64 20 70 65  e a formatted pe
2250: 72 63 65 6e 74 61 67 65 20 76 61 6c 75 65 20 66  rcentage value f
2260: 6f 72 20 24 6e 75 6d 2f 24 64 65 6e 6f 6d 0a 23  or $num/$denom.#
2270: 0a 70 72 6f 63 20 70 65 72 63 65 6e 74 20 7b 6e  .proc percent {n
2280: 75 6d 20 64 65 6e 6f 6d 20 7b 6f 66 20 7b 7d 7d  um denom {of {}}
2290: 7d 20 7b 0a 20 20 69 66 20 7b 24 64 65 6e 6f 6d  } {.  if {$denom
22a0: 3d 3d 30 2e 30 7d 20 7b 72 65 74 75 72 6e 20 22  ==0.0} {return "
22b0: 22 7d 0a 20 20 73 65 74 20 76 20 5b 65 78 70 72  "}.  set v [expr
22c0: 20 7b 24 6e 75 6d 2a 31 30 30 2e 30 2f 24 64 65   {$num*100.0/$de
22d0: 6e 6f 6d 7d 5d 0a 20 20 73 65 74 20 6f 66 20 7b  nom}].  set of {
22e0: 7d 0a 20 20 69 66 20 7b 24 76 3d 3d 31 30 30 2e  }.  if {$v==100.
22f0: 30 20 7c 7c 20 24 76 3c 30 2e 30 30 31 20 7c 7c  0 || $v<0.001 ||
2300: 20 28 24 76 3e 31 2e 30 20 26 26 20 24 76 3c 39   ($v>1.0 && $v<9
2310: 39 2e 30 29 7d 20 7b 0a 20 20 20 20 72 65 74 75  9.0)} {.    retu
2320: 72 6e 20 5b 66 6f 72 6d 61 74 20 7b 25 35 2e 31  rn [format {%5.1
2330: 66 25 25 20 25 73 7d 20 24 76 20 24 6f 66 5d 0a  f%% %s} $v $of].
2340: 20 20 7d 20 65 6c 73 65 69 66 20 7b 24 76 3c 30    } elseif {$v<0
2350: 2e 31 20 7c 7c 20 24 76 3e 39 39 2e 39 7d 20 7b  .1 || $v>99.9} {
2360: 0a 20 20 20 20 72 65 74 75 72 6e 20 5b 66 6f 72  .    return [for
2370: 6d 61 74 20 7b 25 37 2e 33 66 25 25 20 25 73 7d  mat {%7.3f%% %s}
2380: 20 24 76 20 24 6f 66 5d 0a 20 20 7d 20 65 6c 73   $v $of].  } els
2390: 65 20 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 5b  e {.    return [
23a0: 66 6f 72 6d 61 74 20 7b 25 36 2e 32 66 25 25 20  format {%6.2f%% 
23b0: 25 73 7d 20 24 76 20 24 6f 66 5d 0a 20 20 7d 0a  %s} $v $of].  }.
23c0: 7d 0a 0a 70 72 6f 63 20 64 69 76 69 64 65 20 7b  }..proc divide {
23d0: 6e 75 6d 20 64 65 6e 6f 6d 7d 20 7b 0a 20 20 69  num denom} {.  i
23e0: 66 20 7b 24 64 65 6e 6f 6d 3d 3d 30 7d 20 7b 72  f {$denom==0} {r
23f0: 65 74 75 72 6e 20 30 2e 30 7d 0a 20 20 72 65 74  eturn 0.0}.  ret
2400: 75 72 6e 20 5b 66 6f 72 6d 61 74 20 25 2e 32 66  urn [format %.2f
2410: 20 5b 65 78 70 72 20 64 6f 75 62 6c 65 28 24 6e   [expr double($n
2420: 75 6d 29 2f 64 6f 75 62 6c 65 28 24 64 65 6e 6f  um)/double($deno
2430: 6d 29 5d 5d 0a 7d 0a 0a 23 20 47 65 6e 65 72 61  m)]].}..# Genera
2440: 74 65 20 61 20 73 75 62 72 65 70 6f 72 74 20 74  te a subreport t
2450: 68 61 74 20 63 6f 76 65 72 73 20 73 6f 6d 65 20  hat covers some 
2460: 73 75 62 73 65 74 20 6f 66 20 74 68 65 20 64 61  subset of the da
2470: 74 61 62 61 73 65 2e 0a 23 20 74 68 65 20 24 77  tabase..# the $w
2480: 68 65 72 65 20 63 6c 61 75 73 65 20 64 65 74 65  here clause dete
2490: 72 6d 69 6e 65 73 20 77 68 69 63 68 20 73 75 62  rmines which sub
24a0: 73 65 74 20 74 6f 20 61 6e 61 6c 79 7a 65 2e 0a  set to analyze..
24b0: 23 0a 70 72 6f 63 20 73 75 62 72 65 70 6f 72 74  #.proc subreport
24c0: 20 7b 74 69 74 6c 65 20 77 68 65 72 65 20 73 68   {title where sh
24d0: 6f 77 46 72 61 67 7d 20 7b 0a 20 20 67 6c 6f 62  owFrag} {.  glob
24e0: 61 6c 20 70 61 67 65 53 69 7a 65 20 66 69 6c 65  al pageSize file
24f0: 5f 70 67 63 6e 74 20 63 6f 6d 70 72 65 73 73 4f  _pgcnt compressO
2500: 76 65 72 68 65 61 64 0a 0a 20 20 23 20 51 75 65  verhead..  # Que
2510: 72 79 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79  ry the in-memory
2520: 20 64 61 74 61 62 61 73 65 20 66 6f 72 20 74 68   database for th
2530: 65 20 73 75 6d 20 6f 66 20 76 61 72 69 6f 75 73  e sum of various
2540: 20 73 74 61 74 69 73 74 69 63 73 20 0a 20 20 23   statistics .  #
2550: 20 66 6f 72 20 74 68 65 20 73 75 62 73 65 74 20   for the subset 
2560: 6f 66 20 74 61 62 6c 65 73 2f 69 6e 64 69 63 65  of tables/indice
2570: 73 20 69 64 65 6e 74 69 66 69 65 64 20 62 79 20  s identified by 
2580: 74 68 65 20 57 48 45 52 45 20 63 6c 61 75 73 65  the WHERE clause
2590: 20 69 6e 0a 20 20 23 20 24 77 68 65 72 65 2e 20   in.  # $where. 
25a0: 4e 6f 74 65 20 74 68 61 74 20 65 76 65 6e 20 69  Note that even i
25b0: 66 20 74 68 65 20 57 48 45 52 45 20 63 6c 61 75  f the WHERE clau
25c0: 73 65 20 6d 61 74 63 68 65 73 20 6e 6f 20 72 6f  se matches no ro
25d0: 77 73 2c 20 74 68 65 0a 20 20 23 20 66 6f 6c 6c  ws, the.  # foll
25e0: 6f 77 69 6e 67 20 71 75 65 72 79 20 72 65 74 75  owing query retu
25f0: 72 6e 73 20 65 78 61 63 74 6c 79 20 6f 6e 65 20  rns exactly one 
2600: 72 6f 77 20 28 62 65 63 61 75 73 65 20 69 74 20  row (because it 
2610: 69 73 20 61 6e 20 61 67 67 72 65 67 61 74 65 29  is an aggregate)
2620: 2e 0a 20 20 23 0a 20 20 23 20 54 68 65 20 72 65  ..  #.  # The re
2630: 73 75 6c 74 73 20 6f 66 20 74 68 65 20 71 75 65  sults of the que
2640: 72 79 20 61 72 65 20 73 74 6f 72 65 64 20 64 69  ry are stored di
2650: 72 65 63 74 6c 79 20 62 79 20 53 51 4c 69 74 65  rectly by SQLite
2660: 20 69 6e 74 6f 20 6c 6f 63 61 6c 20 0a 20 20 23   into local .  #
2670: 20 76 61 72 69 61 62 6c 65 73 20 28 69 2e 65 2e   variables (i.e.
2680: 20 24 6e 65 6e 74 72 79 2c 20 24 6e 6c 65 61 66   $nentry, $nleaf
2690: 20 65 74 63 2e 29 2e 0a 20 20 23 0a 20 20 6d 65   etc.)..  #.  me
26a0: 6d 20 65 76 61 6c 20 22 0a 20 20 20 20 53 45 4c  m eval ".    SEL
26b0: 45 43 54 0a 20 20 20 20 20 20 69 6e 74 28 73 75  ECT.      int(su
26c0: 6d 28 6e 65 6e 74 72 79 29 29 20 41 53 20 6e 65  m(nentry)) AS ne
26d0: 6e 74 72 79 2c 0a 20 20 20 20 20 20 69 6e 74 28  ntry,.      int(
26e0: 73 75 6d 28 6c 65 61 66 5f 65 6e 74 72 69 65 73  sum(leaf_entries
26f0: 29 29 20 41 53 20 6e 6c 65 61 66 2c 0a 20 20 20  )) AS nleaf,.   
2700: 20 20 20 69 6e 74 28 73 75 6d 28 70 61 79 6c 6f     int(sum(paylo
2710: 61 64 29 29 20 41 53 20 70 61 79 6c 6f 61 64 2c  ad)) AS payload,
2720: 0a 20 20 20 20 20 20 69 6e 74 28 73 75 6d 28 6f  .      int(sum(o
2730: 76 66 6c 5f 70 61 79 6c 6f 61 64 29 29 20 41 53  vfl_payload)) AS
2740: 20 6f 76 66 6c 5f 70 61 79 6c 6f 61 64 2c 0a 20   ovfl_payload,. 
2750: 20 20 20 20 20 6d 61 78 28 6d 78 5f 70 61 79 6c       max(mx_payl
2760: 6f 61 64 29 20 41 53 20 6d 78 5f 70 61 79 6c 6f  oad) AS mx_paylo
2770: 61 64 2c 0a 20 20 20 20 20 20 69 6e 74 28 73 75  ad,.      int(su
2780: 6d 28 6f 76 66 6c 5f 63 6e 74 29 29 20 61 73 20  m(ovfl_cnt)) as 
2790: 6f 76 66 6c 5f 63 6e 74 2c 0a 20 20 20 20 20 20  ovfl_cnt,.      
27a0: 69 6e 74 28 73 75 6d 28 6c 65 61 66 5f 70 61 67  int(sum(leaf_pag
27b0: 65 73 29 29 20 41 53 20 6c 65 61 66 5f 70 61 67  es)) AS leaf_pag
27c0: 65 73 2c 0a 20 20 20 20 20 20 69 6e 74 28 73 75  es,.      int(su
27d0: 6d 28 69 6e 74 5f 70 61 67 65 73 29 29 20 41 53  m(int_pages)) AS
27e0: 20 69 6e 74 5f 70 61 67 65 73 2c 0a 20 20 20 20   int_pages,.    
27f0: 20 20 69 6e 74 28 73 75 6d 28 6f 76 66 6c 5f 70    int(sum(ovfl_p
2800: 61 67 65 73 29 29 20 41 53 20 6f 76 66 6c 5f 70  ages)) AS ovfl_p
2810: 61 67 65 73 2c 0a 20 20 20 20 20 20 69 6e 74 28  ages,.      int(
2820: 73 75 6d 28 6c 65 61 66 5f 75 6e 75 73 65 64 29  sum(leaf_unused)
2830: 29 20 41 53 20 6c 65 61 66 5f 75 6e 75 73 65 64  ) AS leaf_unused
2840: 2c 0a 20 20 20 20 20 20 69 6e 74 28 73 75 6d 28  ,.      int(sum(
2850: 69 6e 74 5f 75 6e 75 73 65 64 29 29 20 41 53 20  int_unused)) AS 
2860: 69 6e 74 5f 75 6e 75 73 65 64 2c 0a 20 20 20 20  int_unused,.    
2870: 20 20 69 6e 74 28 73 75 6d 28 6f 76 66 6c 5f 75    int(sum(ovfl_u
2880: 6e 75 73 65 64 29 29 20 41 53 20 6f 76 66 6c 5f  nused)) AS ovfl_
2890: 75 6e 75 73 65 64 2c 0a 20 20 20 20 20 20 69 6e  unused,.      in
28a0: 74 28 73 75 6d 28 67 61 70 5f 63 6e 74 29 29 20  t(sum(gap_cnt)) 
28b0: 41 53 20 67 61 70 5f 63 6e 74 2c 0a 20 20 20 20  AS gap_cnt,.    
28c0: 20 20 69 6e 74 28 73 75 6d 28 63 6f 6d 70 72 65    int(sum(compre
28d0: 73 73 65 64 5f 73 69 7a 65 29 29 20 41 53 20 63  ssed_size)) AS c
28e0: 6f 6d 70 72 65 73 73 65 64 5f 73 69 7a 65 0a 20  ompressed_size. 
28f0: 20 20 20 46 52 4f 4d 20 73 70 61 63 65 5f 75 73     FROM space_us
2900: 65 64 20 57 48 45 52 45 20 24 77 68 65 72 65 22  ed WHERE $where"
2910: 20 7b 7d 20 7b 7d 0a 0a 20 20 23 20 4f 75 74 70   {} {}..  # Outp
2920: 75 74 20 74 68 65 20 73 75 62 2d 72 65 70 6f 72  ut the sub-repor
2930: 74 20 74 69 74 6c 65 2c 20 6e 69 63 65 6c 79 20  t title, nicely 
2940: 64 65 63 6f 72 61 74 65 64 20 77 69 74 68 20 2a  decorated with *
2950: 20 63 68 61 72 61 63 74 65 72 73 2e 0a 20 20 23   characters..  #
2960: 0a 20 20 70 75 74 73 20 22 22 0a 20 20 74 69 74  .  puts "".  tit
2970: 6c 65 6c 69 6e 65 20 24 74 69 74 6c 65 0a 20 20  leline $title.  
2980: 70 75 74 73 20 22 22 0a 0a 20 20 23 20 43 61 6c  puts ""..  # Cal
2990: 63 75 6c 61 74 65 20 73 74 61 74 69 73 74 69 63  culate statistic
29a0: 73 20 61 6e 64 20 73 74 6f 72 65 20 74 68 65 20  s and store the 
29b0: 72 65 73 75 6c 74 73 20 69 6e 20 54 43 4c 20 76  results in TCL v
29c0: 61 72 69 61 62 6c 65 73 2c 20 61 73 20 66 6f 6c  ariables, as fol
29d0: 6c 6f 77 73 3a 0a 20 20 23 0a 20 20 23 20 74 6f  lows:.  #.  # to
29e0: 74 61 6c 5f 70 61 67 65 73 3a 20 44 61 74 61 62  tal_pages: Datab
29f0: 61 73 65 20 70 61 67 65 73 20 63 6f 6e 73 75 6d  ase pages consum
2a00: 65 64 2e 0a 20 20 23 20 74 6f 74 61 6c 5f 70 61  ed..  # total_pa
2a10: 67 65 73 5f 70 65 72 63 65 6e 74 3a 20 50 61 67  ges_percent: Pag
2a20: 65 73 20 63 6f 6e 73 75 6d 65 64 20 61 73 20 61  es consumed as a
2a30: 20 70 65 72 63 65 6e 74 61 67 65 20 6f 66 20 74   percentage of t
2a40: 68 65 20 66 69 6c 65 2e 0a 20 20 23 20 73 74 6f  he file..  # sto
2a50: 72 61 67 65 3a 20 42 79 74 65 73 20 63 6f 6e 73  rage: Bytes cons
2a60: 75 6d 65 64 2e 0a 20 20 23 20 70 61 79 6c 6f 61  umed..  # payloa
2a70: 64 5f 70 65 72 63 65 6e 74 3a 20 50 61 79 6c 6f  d_percent: Paylo
2a80: 61 64 20 62 79 74 65 73 20 75 73 65 64 20 61 73  ad bytes used as
2a90: 20 61 20 70 65 72 63 65 6e 74 61 67 65 20 6f 66   a percentage of
2aa0: 20 24 73 74 6f 72 61 67 65 2e 0a 20 20 23 20 74   $storage..  # t
2ab0: 6f 74 61 6c 5f 75 6e 75 73 65 64 3a 20 55 6e 75  otal_unused: Unu
2ac0: 73 65 64 20 62 79 74 65 73 20 6f 6e 20 70 61 67  sed bytes on pag
2ad0: 65 73 2e 0a 20 20 23 20 61 76 67 5f 70 61 79 6c  es..  # avg_payl
2ae0: 6f 61 64 3a 20 41 76 65 72 61 67 65 20 70 61 79  oad: Average pay
2af0: 6c 6f 61 64 20 70 65 72 20 62 74 72 65 65 20 65  load per btree e
2b00: 6e 74 72 79 2e 0a 20 20 23 20 61 76 67 5f 66 61  ntry..  # avg_fa
2b10: 6e 6f 75 74 3a 20 41 76 65 72 61 67 65 20 66 61  nout: Average fa
2b20: 6e 6f 75 74 20 66 6f 72 20 69 6e 74 65 72 6e 61  nout for interna
2b30: 6c 20 70 61 67 65 73 2e 0a 20 20 23 20 61 76 67  l pages..  # avg
2b40: 5f 75 6e 75 73 65 64 3a 20 41 76 65 72 61 67 65  _unused: Average
2b50: 20 75 6e 75 73 65 64 20 62 79 74 65 73 20 70 65   unused bytes pe
2b60: 72 20 62 74 72 65 65 20 65 6e 74 72 79 2e 0a 20  r btree entry.. 
2b70: 20 23 20 6f 76 66 6c 5f 63 6e 74 5f 70 65 72 63   # ovfl_cnt_perc
2b80: 65 6e 74 3a 20 50 65 72 63 65 6e 74 61 67 65 20  ent: Percentage 
2b90: 6f 66 20 62 74 72 65 65 20 65 6e 74 72 69 65 73  of btree entries
2ba0: 20 74 68 61 74 20 75 73 65 20 6f 76 65 72 66 6c   that use overfl
2bb0: 6f 77 20 70 61 67 65 73 2e 0a 20 20 23 0a 20 20  ow pages..  #.  
2bc0: 73 65 74 20 74 6f 74 61 6c 5f 70 61 67 65 73 20  set total_pages 
2bd0: 5b 65 78 70 72 20 7b 24 6c 65 61 66 5f 70 61 67  [expr {$leaf_pag
2be0: 65 73 2b 24 69 6e 74 5f 70 61 67 65 73 2b 24 6f  es+$int_pages+$o
2bf0: 76 66 6c 5f 70 61 67 65 73 7d 5d 0a 20 20 73 65  vfl_pages}].  se
2c00: 74 20 74 6f 74 61 6c 5f 70 61 67 65 73 5f 70 65  t total_pages_pe
2c10: 72 63 65 6e 74 20 5b 70 65 72 63 65 6e 74 20 24  rcent [percent $
2c20: 74 6f 74 61 6c 5f 70 61 67 65 73 20 24 66 69 6c  total_pages $fil
2c30: 65 5f 70 67 63 6e 74 5d 0a 20 20 73 65 74 20 73  e_pgcnt].  set s
2c40: 74 6f 72 61 67 65 20 5b 65 78 70 72 20 7b 24 74  torage [expr {$t
2c50: 6f 74 61 6c 5f 70 61 67 65 73 2a 24 70 61 67 65  otal_pages*$page
2c60: 53 69 7a 65 7d 5d 0a 20 20 73 65 74 20 70 61 79  Size}].  set pay
2c70: 6c 6f 61 64 5f 70 65 72 63 65 6e 74 20 5b 70 65  load_percent [pe
2c80: 72 63 65 6e 74 20 24 70 61 79 6c 6f 61 64 20 24  rcent $payload $
2c90: 73 74 6f 72 61 67 65 20 7b 6f 66 20 73 74 6f 72  storage {of stor
2ca0: 61 67 65 20 63 6f 6e 73 75 6d 65 64 7d 5d 0a 20  age consumed}]. 
2cb0: 20 73 65 74 20 74 6f 74 61 6c 5f 75 6e 75 73 65   set total_unuse
2cc0: 64 20 5b 65 78 70 72 20 7b 24 6f 76 66 6c 5f 75  d [expr {$ovfl_u
2cd0: 6e 75 73 65 64 2b 24 69 6e 74 5f 75 6e 75 73 65  nused+$int_unuse
2ce0: 64 2b 24 6c 65 61 66 5f 75 6e 75 73 65 64 7d 5d  d+$leaf_unused}]
2cf0: 0a 20 20 73 65 74 20 61 76 67 5f 70 61 79 6c 6f  .  set avg_paylo
2d00: 61 64 20 5b 64 69 76 69 64 65 20 24 70 61 79 6c  ad [divide $payl
2d10: 6f 61 64 20 24 6e 6c 65 61 66 5d 0a 20 20 73 65  oad $nleaf].  se
2d20: 74 20 61 76 67 5f 75 6e 75 73 65 64 20 5b 64 69  t avg_unused [di
2d30: 76 69 64 65 20 24 74 6f 74 61 6c 5f 75 6e 75 73  vide $total_unus
2d40: 65 64 20 24 6e 6c 65 61 66 5d 0a 20 20 69 66 20  ed $nleaf].  if 
2d50: 7b 24 69 6e 74 5f 70 61 67 65 73 3e 30 7d 20 7b  {$int_pages>0} {
2d60: 0a 20 20 20 20 23 20 54 4f 44 4f 3a 20 49 73 20  .    # TODO: Is 
2d70: 74 68 69 73 20 66 6f 72 6d 75 6c 61 20 63 6f 72  this formula cor
2d80: 72 65 63 74 3f 0a 20 20 20 20 73 65 74 20 6e 54  rect?.    set nT
2d90: 61 62 20 5b 6d 65 6d 20 65 76 61 6c 20 22 0a 20  ab [mem eval ". 
2da0: 20 20 20 20 20 53 45 4c 45 43 54 20 63 6f 75 6e       SELECT coun
2db0: 74 28 2a 29 20 46 52 4f 4d 20 28 0a 20 20 20 20  t(*) FROM (.    
2dc0: 20 20 20 20 20 20 53 45 4c 45 43 54 20 44 49 53        SELECT DIS
2dd0: 54 49 4e 43 54 20 74 62 6c 6e 61 6d 65 20 46 52  TINCT tblname FR
2de0: 4f 4d 20 73 70 61 63 65 5f 75 73 65 64 20 57 48  OM space_used WH
2df0: 45 52 45 20 24 77 68 65 72 65 20 41 4e 44 20 69  ERE $where AND i
2e00: 73 5f 69 6e 64 65 78 3d 30 0a 20 20 20 20 20 20  s_index=0.      
2e10: 29 0a 20 20 20 20 22 5d 0a 20 20 20 20 73 65 74  ).    "].    set
2e20: 20 61 76 67 5f 66 61 6e 6f 75 74 20 5b 6d 65 6d   avg_fanout [mem
2e30: 20 65 76 61 6c 20 22 0a 20 20 20 20 20 20 53 45   eval ".      SE
2e40: 4c 45 43 54 20 28 73 75 6d 28 6c 65 61 66 5f 70  LECT (sum(leaf_p
2e50: 61 67 65 73 2b 69 6e 74 5f 70 61 67 65 73 29 2d  ages+int_pages)-
2e60: 24 6e 54 61 62 29 2f 73 75 6d 28 69 6e 74 5f 70  $nTab)/sum(int_p
2e70: 61 67 65 73 29 20 46 52 4f 4d 20 73 70 61 63 65  ages) FROM space
2e80: 5f 75 73 65 64 0a 20 20 20 20 20 20 20 20 20 20  _used.          
2e90: 57 48 45 52 45 20 24 77 68 65 72 65 20 41 4e 44  WHERE $where AND
2ea0: 20 69 73 5f 69 6e 64 65 78 20 3d 20 30 0a 20 20   is_index = 0.  
2eb0: 20 20 22 5d 0a 20 20 20 20 73 65 74 20 61 76 67    "].    set avg
2ec0: 5f 66 61 6e 6f 75 74 20 5b 66 6f 72 6d 61 74 20  _fanout [format 
2ed0: 25 2e 32 66 20 24 61 76 67 5f 66 61 6e 6f 75 74  %.2f $avg_fanout
2ee0: 5d 0a 20 20 7d 0a 20 20 73 65 74 20 6f 76 66 6c  ].  }.  set ovfl
2ef0: 5f 63 6e 74 5f 70 65 72 63 65 6e 74 20 5b 70 65  _cnt_percent [pe
2f00: 72 63 65 6e 74 20 24 6f 76 66 6c 5f 63 6e 74 20  rcent $ovfl_cnt 
2f10: 24 6e 6c 65 61 66 20 7b 6f 66 20 61 6c 6c 20 65  $nleaf {of all e
2f20: 6e 74 72 69 65 73 7d 5d 0a 0a 20 20 23 20 50 72  ntries}]..  # Pr
2f30: 69 6e 74 20 6f 75 74 20 74 68 65 20 73 75 62 2d  int out the sub-
2f40: 72 65 70 6f 72 74 20 73 74 61 74 69 73 74 69 63  report statistic
2f50: 73 2e 0a 20 20 23 0a 20 20 73 74 61 74 6c 69 6e  s..  #.  statlin
2f60: 65 20 7b 50 65 72 63 65 6e 74 61 67 65 20 6f 66  e {Percentage of
2f70: 20 74 6f 74 61 6c 20 64 61 74 61 62 61 73 65 7d   total database}
2f80: 20 24 74 6f 74 61 6c 5f 70 61 67 65 73 5f 70 65   $total_pages_pe
2f90: 72 63 65 6e 74 0a 20 20 73 74 61 74 6c 69 6e 65  rcent.  statline
2fa0: 20 7b 4e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72   {Number of entr
2fb0: 69 65 73 7d 20 24 6e 6c 65 61 66 0a 20 20 73 74  ies} $nleaf.  st
2fc0: 61 74 6c 69 6e 65 20 7b 42 79 74 65 73 20 6f 66  atline {Bytes of
2fd0: 20 73 74 6f 72 61 67 65 20 63 6f 6e 73 75 6d 65   storage consume
2fe0: 64 7d 20 24 73 74 6f 72 61 67 65 0a 20 20 69 66  d} $storage.  if
2ff0: 20 7b 24 63 6f 6d 70 72 65 73 73 65 64 5f 73 69   {$compressed_si
3000: 7a 65 21 3d 24 73 74 6f 72 61 67 65 7d 20 7b 0a  ze!=$storage} {.
3010: 20 20 20 20 73 65 74 20 63 6f 6d 70 72 65 73 73      set compress
3020: 65 64 5f 73 69 7a 65 20 5b 65 78 70 72 20 7b 24  ed_size [expr {$
3030: 63 6f 6d 70 72 65 73 73 65 64 5f 73 69 7a 65 2b  compressed_size+
3040: 24 63 6f 6d 70 72 65 73 73 4f 76 65 72 68 65 61  $compressOverhea
3050: 64 2a 24 74 6f 74 61 6c 5f 70 61 67 65 73 7d 5d  d*$total_pages}]
3060: 0a 20 20 20 20 73 65 74 20 70 63 74 20 5b 65 78  .    set pct [ex
3070: 70 72 20 7b 24 63 6f 6d 70 72 65 73 73 65 64 5f  pr {$compressed_
3080: 73 69 7a 65 2a 31 30 30 2e 30 2f 24 73 74 6f 72  size*100.0/$stor
3090: 61 67 65 7d 5d 0a 20 20 20 20 73 65 74 20 70 63  age}].    set pc
30a0: 74 20 5b 66 6f 72 6d 61 74 20 7b 25 35 2e 31 66  t [format {%5.1f
30b0: 25 25 7d 20 24 70 63 74 5d 0a 20 20 20 20 73 74  %%} $pct].    st
30c0: 61 74 6c 69 6e 65 20 7b 42 79 74 65 73 20 75 73  atline {Bytes us
30d0: 65 64 20 61 66 74 65 72 20 63 6f 6d 70 72 65 73  ed after compres
30e0: 73 69 6f 6e 7d 20 24 63 6f 6d 70 72 65 73 73 65  sion} $compresse
30f0: 64 5f 73 69 7a 65 20 24 70 63 74 0a 20 20 7d 0a  d_size $pct.  }.
3100: 20 20 73 74 61 74 6c 69 6e 65 20 7b 42 79 74 65    statline {Byte
3110: 73 20 6f 66 20 70 61 79 6c 6f 61 64 7d 20 24 70  s of payload} $p
3120: 61 79 6c 6f 61 64 20 24 70 61 79 6c 6f 61 64 5f  ayload $payload_
3130: 70 65 72 63 65 6e 74 0a 20 20 73 74 61 74 6c 69  percent.  statli
3140: 6e 65 20 7b 41 76 65 72 61 67 65 20 70 61 79 6c  ne {Average payl
3150: 6f 61 64 20 70 65 72 20 65 6e 74 72 79 7d 20 24  oad per entry} $
3160: 61 76 67 5f 70 61 79 6c 6f 61 64 0a 20 20 73 74  avg_payload.  st
3170: 61 74 6c 69 6e 65 20 7b 41 76 65 72 61 67 65 20  atline {Average 
3180: 75 6e 75 73 65 64 20 62 79 74 65 73 20 70 65 72  unused bytes per
3190: 20 65 6e 74 72 79 7d 20 24 61 76 67 5f 75 6e 75   entry} $avg_unu
31a0: 73 65 64 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20  sed.  if {[info 
31b0: 65 78 69 73 74 73 20 61 76 67 5f 66 61 6e 6f 75  exists avg_fanou
31c0: 74 5d 7d 20 7b 0a 20 20 20 20 73 74 61 74 6c 69  t]} {.    statli
31d0: 6e 65 20 7b 41 76 65 72 61 67 65 20 66 61 6e 6f  ne {Average fano
31e0: 75 74 7d 20 24 61 76 67 5f 66 61 6e 6f 75 74 0a  ut} $avg_fanout.
31f0: 20 20 7d 0a 20 20 69 66 20 7b 24 73 68 6f 77 46    }.  if {$showF
3200: 72 61 67 20 26 26 20 24 74 6f 74 61 6c 5f 70 61  rag && $total_pa
3210: 67 65 73 3e 31 7d 20 7b 0a 20 20 20 20 73 65 74  ges>1} {.    set
3220: 20 66 72 61 67 6d 65 6e 74 61 74 69 6f 6e 20 5b   fragmentation [
3230: 70 65 72 63 65 6e 74 20 24 67 61 70 5f 63 6e 74  percent $gap_cnt
3240: 20 5b 65 78 70 72 20 7b 24 74 6f 74 61 6c 5f 70   [expr {$total_p
3250: 61 67 65 73 2d 31 7d 5d 5d 0a 20 20 20 20 73 74  ages-1}]].    st
3260: 61 74 6c 69 6e 65 20 7b 4e 6f 6e 2d 73 65 71 75  atline {Non-sequ
3270: 65 6e 74 69 61 6c 20 70 61 67 65 73 7d 20 24 67  ential pages} $g
3280: 61 70 5f 63 6e 74 20 24 66 72 61 67 6d 65 6e 74  ap_cnt $fragment
3290: 61 74 69 6f 6e 0a 20 20 7d 0a 20 20 73 74 61 74  ation.  }.  stat
32a0: 6c 69 6e 65 20 7b 4d 61 78 69 6d 75 6d 20 70 61  line {Maximum pa
32b0: 79 6c 6f 61 64 20 70 65 72 20 65 6e 74 72 79 7d  yload per entry}
32c0: 20 24 6d 78 5f 70 61 79 6c 6f 61 64 0a 20 20 73   $mx_payload.  s
32d0: 74 61 74 6c 69 6e 65 20 7b 45 6e 74 72 69 65 73  tatline {Entries
32e0: 20 74 68 61 74 20 75 73 65 20 6f 76 65 72 66 6c   that use overfl
32f0: 6f 77 7d 20 24 6f 76 66 6c 5f 63 6e 74 20 24 6f  ow} $ovfl_cnt $o
3300: 76 66 6c 5f 63 6e 74 5f 70 65 72 63 65 6e 74 0a  vfl_cnt_percent.
3310: 20 20 69 66 20 7b 24 69 6e 74 5f 70 61 67 65 73    if {$int_pages
3320: 3e 30 7d 20 7b 0a 20 20 20 20 73 74 61 74 6c 69  >0} {.    statli
3330: 6e 65 20 7b 49 6e 64 65 78 20 70 61 67 65 73 20  ne {Index pages 
3340: 75 73 65 64 7d 20 24 69 6e 74 5f 70 61 67 65 73  used} $int_pages
3350: 0a 20 20 7d 0a 20 20 73 74 61 74 6c 69 6e 65 20  .  }.  statline 
3360: 7b 50 72 69 6d 61 72 79 20 70 61 67 65 73 20 75  {Primary pages u
3370: 73 65 64 7d 20 24 6c 65 61 66 5f 70 61 67 65 73  sed} $leaf_pages
3380: 0a 20 20 73 74 61 74 6c 69 6e 65 20 7b 4f 76 65  .  statline {Ove
3390: 72 66 6c 6f 77 20 70 61 67 65 73 20 75 73 65 64  rflow pages used
33a0: 7d 20 24 6f 76 66 6c 5f 70 61 67 65 73 0a 20 20  } $ovfl_pages.  
33b0: 73 74 61 74 6c 69 6e 65 20 7b 54 6f 74 61 6c 20  statline {Total 
33c0: 70 61 67 65 73 20 75 73 65 64 7d 20 24 74 6f 74  pages used} $tot
33d0: 61 6c 5f 70 61 67 65 73 0a 20 20 69 66 20 7b 24  al_pages.  if {$
33e0: 69 6e 74 5f 75 6e 75 73 65 64 3e 30 7d 20 7b 0a  int_unused>0} {.
33f0: 20 20 20 20 73 65 74 20 69 6e 74 5f 75 6e 75 73      set int_unus
3400: 65 64 5f 70 65 72 63 65 6e 74 20 5b 0a 20 20 20  ed_percent [.   
3410: 20 20 20 20 20 20 70 65 72 63 65 6e 74 20 24 69        percent $i
3420: 6e 74 5f 75 6e 75 73 65 64 20 5b 65 78 70 72 20  nt_unused [expr 
3430: 7b 24 69 6e 74 5f 70 61 67 65 73 2a 24 70 61 67  {$int_pages*$pag
3440: 65 53 69 7a 65 7d 5d 20 7b 6f 66 20 69 6e 64 65  eSize}] {of inde
3450: 78 20 73 70 61 63 65 7d 5d 0a 20 20 20 20 73 74  x space}].    st
3460: 61 74 6c 69 6e 65 20 22 55 6e 75 73 65 64 20 62  atline "Unused b
3470: 79 74 65 73 20 6f 6e 20 69 6e 64 65 78 20 70 61  ytes on index pa
3480: 67 65 73 22 20 24 69 6e 74 5f 75 6e 75 73 65 64  ges" $int_unused
3490: 20 24 69 6e 74 5f 75 6e 75 73 65 64 5f 70 65 72   $int_unused_per
34a0: 63 65 6e 74 0a 20 20 7d 0a 20 20 73 74 61 74 6c  cent.  }.  statl
34b0: 69 6e 65 20 22 55 6e 75 73 65 64 20 62 79 74 65  ine "Unused byte
34c0: 73 20 6f 6e 20 70 72 69 6d 61 72 79 20 70 61 67  s on primary pag
34d0: 65 73 22 20 24 6c 65 61 66 5f 75 6e 75 73 65 64  es" $leaf_unused
34e0: 20 5b 0a 20 20 20 20 20 70 65 72 63 65 6e 74 20   [.     percent 
34f0: 24 6c 65 61 66 5f 75 6e 75 73 65 64 20 5b 65 78  $leaf_unused [ex
3500: 70 72 20 7b 24 6c 65 61 66 5f 70 61 67 65 73 2a  pr {$leaf_pages*
3510: 24 70 61 67 65 53 69 7a 65 7d 5d 20 7b 6f 66 20  $pageSize}] {of 
3520: 70 72 69 6d 61 72 79 20 73 70 61 63 65 7d 5d 0a  primary space}].
3530: 20 20 73 74 61 74 6c 69 6e 65 20 22 55 6e 75 73    statline "Unus
3540: 65 64 20 62 79 74 65 73 20 6f 6e 20 6f 76 65 72  ed bytes on over
3550: 66 6c 6f 77 20 70 61 67 65 73 22 20 24 6f 76 66  flow pages" $ovf
3560: 6c 5f 75 6e 75 73 65 64 20 5b 0a 20 20 20 20 20  l_unused [.     
3570: 70 65 72 63 65 6e 74 20 24 6f 76 66 6c 5f 75 6e  percent $ovfl_un
3580: 75 73 65 64 20 5b 65 78 70 72 20 7b 24 6f 76 66  used [expr {$ovf
3590: 6c 5f 70 61 67 65 73 2a 24 70 61 67 65 53 69 7a  l_pages*$pageSiz
35a0: 65 7d 5d 20 7b 6f 66 20 6f 76 65 72 66 6c 6f 77  e}] {of overflow
35b0: 20 73 70 61 63 65 7d 5d 0a 20 20 73 74 61 74 6c   space}].  statl
35c0: 69 6e 65 20 22 55 6e 75 73 65 64 20 62 79 74 65  ine "Unused byte
35d0: 73 20 6f 6e 20 61 6c 6c 20 70 61 67 65 73 22 20  s on all pages" 
35e0: 24 74 6f 74 61 6c 5f 75 6e 75 73 65 64 20 5b 0a  $total_unused [.
35f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70                 p
3600: 65 72 63 65 6e 74 20 24 74 6f 74 61 6c 5f 75 6e  ercent $total_un
3610: 75 73 65 64 20 24 73 74 6f 72 61 67 65 20 7b 6f  used $storage {o
3620: 66 20 61 6c 6c 20 73 70 61 63 65 7d 5d 0a 20 20  f all space}].  
3630: 72 65 74 75 72 6e 20 31 0a 7d 0a 0a 23 20 43 61  return 1.}..# Ca
3640: 6c 63 75 6c 61 74 65 20 74 68 65 20 6f 76 65 72  lculate the over
3650: 68 65 61 64 20 69 6e 20 70 61 67 65 73 20 63 61  head in pages ca
3660: 75 73 65 64 20 62 79 20 61 75 74 6f 2d 76 61 63  used by auto-vac
3670: 75 75 6d 2e 20 0a 23 0a 23 20 54 68 69 73 20 70  uum. .#.# This p
3680: 72 6f 63 65 64 75 72 65 20 63 61 6c 63 75 6c 61  rocedure calcula
3690: 74 65 73 20 61 6e 64 20 72 65 74 75 72 6e 73 20  tes and returns 
36a0: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61  the number of pa
36b0: 67 65 73 20 75 73 65 64 20 62 79 20 74 68 65 20  ges used by the 
36c0: 0a 23 20 61 75 74 6f 2d 76 61 63 75 75 6d 20 27  .# auto-vacuum '
36d0: 70 6f 69 6e 74 65 72 2d 6d 61 70 27 2e 20 49 66  pointer-map'. If
36e0: 20 74 68 65 20 64 61 74 61 62 61 73 65 20 64 6f   the database do
36f0: 65 73 20 6e 6f 74 20 73 75 70 70 6f 72 74 20 61  es not support a
3700: 75 74 6f 2d 76 61 63 75 75 6d 2c 0a 23 20 74 68  uto-vacuum,.# th
3710: 65 6e 20 30 20 69 73 20 72 65 74 75 72 6e 65 64  en 0 is returned
3720: 2e 20 54 68 65 20 74 77 6f 20 61 72 67 75 6d 65  . The two argume
3730: 6e 74 73 20 61 72 65 20 74 68 65 20 73 69 7a 65  nts are the size
3740: 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73 65   of the database
3750: 20 66 69 6c 65 20 69 6e 0a 23 20 70 61 67 65 73   file in.# pages
3760: 20 61 6e 64 20 74 68 65 20 70 61 67 65 20 73 69   and the page si
3770: 7a 65 20 75 73 65 64 20 62 79 20 74 68 65 20 64  ze used by the d
3780: 61 74 61 62 61 73 65 20 28 69 6e 20 62 79 74 65  atabase (in byte
3790: 73 29 2e 0a 70 72 6f 63 20 61 75 74 6f 76 61 63  s)..proc autovac
37a0: 75 75 6d 5f 6f 76 65 72 68 65 61 64 20 7b 66 69  uum_overhead {fi
37b0: 6c 65 50 61 67 65 73 20 70 61 67 65 53 69 7a 65  lePages pageSize
37c0: 7d 20 7b 0a 0a 20 20 23 20 53 65 74 20 24 61 75  } {..  # Set $au
37d0: 74 6f 76 61 63 75 75 6d 20 74 6f 20 6e 6f 6e 2d  tovacuum to non-
37e0: 7a 65 72 6f 20 66 6f 72 20 64 61 74 61 62 61 73  zero for databas
37f0: 65 73 20 74 68 61 74 20 73 75 70 70 6f 72 74 20  es that support 
3800: 61 75 74 6f 2d 76 61 63 75 75 6d 2e 0a 20 20 73  auto-vacuum..  s
3810: 65 74 20 61 75 74 6f 76 61 63 75 75 6d 20 5b 64  et autovacuum [d
3820: 62 20 6f 6e 65 20 7b 50 52 41 47 4d 41 20 61 75  b one {PRAGMA au
3830: 74 6f 5f 76 61 63 75 75 6d 7d 5d 0a 0a 20 20 23  to_vacuum}]..  #
3840: 20 49 66 20 74 68 65 20 64 61 74 61 62 61 73 65   If the database
3850: 20 69 73 20 6e 6f 74 20 61 6e 20 61 75 74 6f 2d   is not an auto-
3860: 76 61 63 75 75 6d 20 64 61 74 61 62 61 73 65 20  vacuum database 
3870: 6f 72 20 74 68 65 20 66 69 6c 65 20 63 6f 6e 73  or the file cons
3880: 69 73 74 73 0a 20 20 23 20 6f 66 20 6f 6e 65 20  ists.  # of one 
3890: 70 61 67 65 20 6f 6e 6c 79 20 74 68 65 6e 20 74  page only then t
38a0: 68 65 72 65 20 69 73 20 6e 6f 20 6f 76 65 72 68  here is no overh
38b0: 65 61 64 20 66 6f 72 20 61 75 74 6f 2d 76 61 63  ead for auto-vac
38c0: 75 75 6d 2e 20 52 65 74 75 72 6e 20 7a 65 72 6f  uum. Return zero
38d0: 2e 0a 20 20 69 66 20 7b 30 3d 3d 24 61 75 74 6f  ..  if {0==$auto
38e0: 76 61 63 75 75 6d 20 7c 7c 20 24 66 69 6c 65 50  vacuum || $fileP
38f0: 61 67 65 73 3d 3d 31 7d 20 7b 0a 20 20 20 20 72  ages==1} {.    r
3900: 65 74 75 72 6e 20 30 0a 20 20 7d 0a 0a 20 20 23  eturn 0.  }..  #
3910: 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 65   The number of e
3920: 6e 74 72 69 65 73 20 6f 6e 20 65 61 63 68 20 70  ntries on each p
3930: 6f 69 6e 74 65 72 20 6d 61 70 20 70 61 67 65 2e  ointer map page.
3940: 20 54 68 65 20 6c 61 79 6f 75 74 20 6f 66 20 74   The layout of t
3950: 68 65 0a 20 20 23 20 64 61 74 61 62 61 73 65 20  he.  # database 
3960: 66 69 6c 65 20 69 73 20 6f 6e 65 20 70 6f 69 6e  file is one poin
3970: 74 65 72 2d 6d 61 70 20 70 61 67 65 2c 20 66 6f  ter-map page, fo
3980: 6c 6c 6f 77 65 64 20 62 79 20 24 70 74 72 73 50  llowed by $ptrsP
3990: 65 72 50 61 67 65 20 6f 74 68 65 72 0a 20 20 23  erPage other.  #
39a0: 20 70 61 67 65 73 2c 20 66 6f 6c 6c 6f 77 65 64   pages, followed
39b0: 20 62 79 20 61 20 70 6f 69 6e 74 65 72 2d 6d 61   by a pointer-ma
39c0: 70 20 70 61 67 65 20 65 74 63 2e 20 54 68 65 20  p page etc. The 
39d0: 66 69 72 73 74 20 70 6f 69 6e 74 65 72 2d 6d 61  first pointer-ma
39e0: 70 20 70 61 67 65 0a 20 20 23 20 69 73 20 74 68  p page.  # is th
39f0: 65 20 73 65 63 6f 6e 64 20 70 61 67 65 20 6f 66  e second page of
3a00: 20 74 68 65 20 66 69 6c 65 20 6f 76 65 72 61 6c   the file overal
3a10: 6c 2e 0a 20 20 73 65 74 20 70 74 72 73 50 65 72  l..  set ptrsPer
3a20: 50 61 67 65 20 5b 65 78 70 72 20 64 6f 75 62 6c  Page [expr doubl
3a30: 65 28 24 70 61 67 65 53 69 7a 65 2f 35 29 5d 0a  e($pageSize/5)].
3a40: 0a 20 20 23 20 52 65 74 75 72 6e 20 74 68 65 20  .  # Return the 
3a50: 6e 75 6d 62 65 72 20 6f 66 20 70 6f 69 6e 74 65  number of pointe
3a60: 72 20 6d 61 70 20 70 61 67 65 73 20 69 6e 20 74  r map pages in t
3a70: 68 65 20 64 61 74 61 62 61 73 65 2e 0a 20 20 72  he database..  r
3a80: 65 74 75 72 6e 20 5b 65 78 70 72 20 77 69 64 65  eturn [expr wide
3a90: 28 63 65 69 6c 28 20 28 24 66 69 6c 65 50 61 67  (ceil( ($filePag
3aa0: 65 73 2d 31 2e 30 29 2f 28 24 70 74 72 73 50 65  es-1.0)/($ptrsPe
3ab0: 72 50 61 67 65 2b 31 2e 30 29 20 29 29 5d 0a 7d  rPage+1.0) ))].}
3ac0: 0a 0a 0a 23 20 43 61 6c 63 75 6c 61 74 65 20 74  ...# Calculate t
3ad0: 68 65 20 73 75 6d 6d 61 72 79 20 73 74 61 74 69  he summary stati
3ae0: 73 74 69 63 73 20 66 6f 72 20 74 68 65 20 64 61  stics for the da
3af0: 74 61 62 61 73 65 20 61 6e 64 20 73 74 6f 72 65  tabase and store
3b00: 20 74 68 65 20 72 65 73 75 6c 74 73 0a 23 20 69   the results.# i
3b10: 6e 20 54 43 4c 20 76 61 72 69 61 62 6c 65 73 2e  n TCL variables.
3b20: 20 54 68 65 79 20 61 72 65 20 6f 75 74 70 75 74   They are output
3b30: 20 62 65 6c 6f 77 2e 20 56 61 72 69 61 62 6c 65   below. Variable
3b40: 73 20 61 72 65 20 61 73 20 66 6f 6c 6c 6f 77 73  s are as follows
3b50: 3a 0a 23 0a 23 20 70 61 67 65 53 69 7a 65 3a 20  :.#.# pageSize: 
3b60: 20 20 20 20 20 53 69 7a 65 20 6f 66 20 65 61 63       Size of eac
3b70: 68 20 70 61 67 65 20 69 6e 20 62 79 74 65 73 2e  h page in bytes.
3b80: 0a 23 20 66 69 6c 65 5f 62 79 74 65 73 3a 20 20  .# file_bytes:  
3b90: 20 20 46 69 6c 65 20 73 69 7a 65 20 69 6e 20 62    File size in b
3ba0: 79 74 65 73 2e 0a 23 20 66 69 6c 65 5f 70 67 63  ytes..# file_pgc
3bb0: 6e 74 3a 20 20 20 20 4e 75 6d 62 65 72 20 6f 66  nt:    Number of
3bc0: 20 70 61 67 65 73 20 69 6e 20 74 68 65 20 66 69   pages in the fi
3bd0: 6c 65 2e 0a 23 20 66 69 6c 65 5f 70 67 63 6e 74  le..# file_pgcnt
3be0: 32 3a 20 20 20 4e 75 6d 62 65 72 20 6f 66 20 70  2:   Number of p
3bf0: 61 67 65 73 20 69 6e 20 74 68 65 20 66 69 6c 65  ages in the file
3c00: 20 28 63 61 6c 63 75 6c 61 74 65 64 29 2e 0a 23   (calculated)..#
3c10: 20 61 76 5f 70 67 63 6e 74 3a 20 20 20 20 20 20   av_pgcnt:      
3c20: 50 61 67 65 73 20 63 6f 6e 73 75 6d 65 64 20 62  Pages consumed b
3c30: 79 20 74 68 65 20 61 75 74 6f 2d 76 61 63 75 75  y the auto-vacuu
3c40: 6d 20 70 6f 69 6e 74 65 72 2d 6d 61 70 2e 0a 23  m pointer-map..#
3c50: 20 61 76 5f 70 65 72 63 65 6e 74 3a 20 20 20 20   av_percent:    
3c60: 50 65 72 63 65 6e 74 61 67 65 20 6f 66 20 74 68  Percentage of th
3c70: 65 20 66 69 6c 65 20 63 6f 6e 73 75 6d 65 64 20  e file consumed 
3c80: 62 79 20 61 75 74 6f 2d 76 61 63 75 75 6d 20 70  by auto-vacuum p
3c90: 6f 69 6e 74 65 72 2d 6d 61 70 2e 0a 23 20 69 6e  ointer-map..# in
3ca0: 75 73 65 5f 70 67 63 6e 74 3a 20 20 20 44 61 74  use_pgcnt:   Dat
3cb0: 61 20 70 61 67 65 73 20 69 6e 20 74 68 65 20 66  a pages in the f
3cc0: 69 6c 65 2e 0a 23 20 69 6e 75 73 65 5f 70 65 72  ile..# inuse_per
3cd0: 63 65 6e 74 3a 20 50 65 72 63 65 6e 74 61 67 65  cent: Percentage
3ce0: 20 6f 66 20 70 61 67 65 73 20 75 73 65 64 20 74   of pages used t
3cf0: 6f 20 73 74 6f 72 65 20 64 61 74 61 2e 0a 23 20  o store data..# 
3d00: 66 72 65 65 5f 70 67 63 6e 74 3a 20 20 20 20 46  free_pgcnt:    F
3d10: 72 65 65 20 70 61 67 65 73 20 63 61 6c 63 75 6c  ree pages calcul
3d20: 61 74 65 64 20 61 73 20 28 3c 74 6f 74 61 6c 20  ated as (<total 
3d30: 70 61 67 65 73 3e 20 2d 20 3c 69 6e 2d 75 73 65  pages> - <in-use
3d40: 20 70 61 67 65 73 3e 29 0a 23 20 66 72 65 65 5f   pages>).# free_
3d50: 70 67 63 6e 74 32 3a 20 20 20 46 72 65 65 20 70  pgcnt2:   Free p
3d60: 61 67 65 73 20 69 6e 20 74 68 65 20 66 69 6c 65  ages in the file
3d70: 20 61 63 63 6f 72 64 69 6e 67 20 74 6f 20 74 68   according to th
3d80: 65 20 66 69 6c 65 20 68 65 61 64 65 72 2e 0a 23  e file header..#
3d90: 20 66 72 65 65 5f 70 65 72 63 65 6e 74 3a 20 20   free_percent:  
3da0: 50 65 72 63 65 6e 74 61 67 65 20 6f 66 20 66 69  Percentage of fi
3db0: 6c 65 20 63 6f 6e 73 75 6d 65 64 20 62 79 20 66  le consumed by f
3dc0: 72 65 65 20 70 61 67 65 73 20 28 63 61 6c 63 75  ree pages (calcu
3dd0: 6c 61 74 65 64 29 2e 0a 23 20 66 72 65 65 5f 70  lated)..# free_p
3de0: 65 72 63 65 6e 74 32 3a 20 50 65 72 63 65 6e 74  ercent2: Percent
3df0: 61 67 65 20 6f 66 20 66 69 6c 65 20 63 6f 6e 73  age of file cons
3e00: 75 6d 65 64 20 62 79 20 66 72 65 65 20 70 61 67  umed by free pag
3e10: 65 73 20 28 68 65 61 64 65 72 29 2e 0a 23 20 6e  es (header)..# n
3e20: 74 61 62 6c 65 3a 20 20 20 20 20 20 20 20 4e 75  table:        Nu
3e30: 6d 62 65 72 20 6f 66 20 74 61 62 6c 65 73 20 69  mber of tables i
3e40: 6e 20 74 68 65 20 64 62 2e 0a 23 20 6e 69 6e 64  n the db..# nind
3e50: 65 78 3a 20 20 20 20 20 20 20 20 4e 75 6d 62 65  ex:        Numbe
3e60: 72 20 6f 66 20 69 6e 64 69 63 65 73 20 69 6e 20  r of indices in 
3e70: 74 68 65 20 64 62 2e 0a 23 20 6e 61 75 74 6f 69  the db..# nautoi
3e80: 6e 64 65 78 3a 20 20 20 20 4e 75 6d 62 65 72 20  ndex:    Number 
3e90: 6f 66 20 69 6e 64 69 63 65 73 20 63 72 65 61 74  of indices creat
3ea0: 65 64 20 61 75 74 6f 6d 61 74 69 63 61 6c 6c 79  ed automatically
3eb0: 2e 0a 23 20 6e 6d 61 6e 69 6e 64 65 78 3a 20 20  ..# nmanindex:  
3ec0: 20 20 20 4e 75 6d 62 65 72 20 6f 66 20 69 6e 64     Number of ind
3ed0: 69 63 65 73 20 63 72 65 61 74 65 64 20 6d 61 6e  ices created man
3ee0: 75 61 6c 6c 79 2e 0a 23 20 75 73 65 72 5f 70 61  ually..# user_pa
3ef0: 79 6c 6f 61 64 3a 20 20 4e 75 6d 62 65 72 20 6f  yload:  Number o
3f00: 66 20 62 79 74 65 73 20 6f 66 20 70 61 79 6c 6f  f bytes of paylo
3f10: 61 64 20 69 6e 20 74 61 62 6c 65 20 62 74 72 65  ad in table btre
3f20: 65 73 20 0a 23 20 20 20 20 20 20 20 20 20 20 20  es .#           
3f30: 20 20 20 20 20 28 6e 6f 74 20 69 6e 63 6c 75 64       (not includ
3f40: 69 6e 67 20 73 71 6c 69 74 65 5f 6d 61 73 74 65  ing sqlite_maste
3f50: 72 29 0a 23 20 75 73 65 72 5f 70 65 72 63 65 6e  r).# user_percen
3f60: 74 3a 20 20 24 75 73 65 72 5f 70 61 79 6c 6f 61  t:  $user_payloa
3f70: 64 20 61 73 20 61 20 70 65 72 63 65 6e 74 61 67  d as a percentag
3f80: 65 20 6f 66 20 74 6f 74 61 6c 20 66 69 6c 65 20  e of total file 
3f90: 73 69 7a 65 2e 0a 0a 23 23 23 20 54 68 65 20 66  size...### The f
3fa0: 6f 6c 6c 6f 77 69 6e 67 2c 20 73 65 74 74 69 6e  ollowing, settin
3fb0: 67 20 24 66 69 6c 65 5f 62 79 74 65 73 20 62 61  g $file_bytes ba
3fc0: 73 65 64 20 6f 6e 20 74 68 65 20 61 63 74 75 61  sed on the actua
3fd0: 6c 20 73 69 7a 65 20 6f 66 20 74 68 65 20 66 69  l size of the fi
3fe0: 6c 65 0a 23 23 23 20 6f 6e 20 64 69 73 6b 2c 20  le.### on disk, 
3ff0: 63 61 75 73 65 73 20 74 68 69 73 20 74 6f 6f 6c  causes this tool
4000: 20 74 6f 20 63 68 6f 6b 65 20 6f 6e 20 7a 69 70   to choke on zip
4010: 76 66 73 20 64 61 74 61 62 61 73 65 73 2e 20 53  vfs databases. S
4020: 6f 20 73 65 74 20 69 74 20 62 61 73 65 64 0a 23  o set it based.#
4030: 23 23 20 6f 6e 20 74 68 65 20 72 65 74 75 72 6e  ## on the return
4040: 20 6f 66 20 5b 50 52 41 47 4d 41 20 70 61 67 65   of [PRAGMA page
4050: 5f 63 6f 75 6e 74 5d 20 69 6e 73 74 65 61 64 2e  _count] instead.
4060: 0a 69 66 20 30 20 7b 0a 20 20 73 65 74 20 66 69  .if 0 {.  set fi
4070: 6c 65 5f 62 79 74 65 73 20 20 5b 66 69 6c 65 20  le_bytes  [file 
4080: 73 69 7a 65 20 24 66 69 6c 65 5f 74 6f 5f 61 6e  size $file_to_an
4090: 61 6c 79 7a 65 5d 0a 20 20 73 65 74 20 66 69 6c  alyze].  set fil
40a0: 65 5f 70 67 63 6e 74 20 20 5b 65 78 70 72 20 7b  e_pgcnt  [expr {
40b0: 24 66 69 6c 65 5f 62 79 74 65 73 2f 24 70 61 67  $file_bytes/$pag
40c0: 65 53 69 7a 65 7d 5d 0a 7d 0a 73 65 74 20 66 69  eSize}].}.set fi
40d0: 6c 65 5f 70 67 63 6e 74 20 20 5b 64 62 20 6f 6e  le_pgcnt  [db on
40e0: 65 20 7b 50 52 41 47 4d 41 20 70 61 67 65 5f 63  e {PRAGMA page_c
40f0: 6f 75 6e 74 7d 5d 0a 73 65 74 20 66 69 6c 65 5f  ount}].set file_
4100: 62 79 74 65 73 20 20 5b 65 78 70 72 20 7b 24 66  bytes  [expr {$f
4110: 69 6c 65 5f 70 67 63 6e 74 20 2a 20 24 70 61 67  ile_pgcnt * $pag
4120: 65 53 69 7a 65 7d 5d 0a 0a 73 65 74 20 61 76 5f  eSize}]..set av_
4130: 70 67 63 6e 74 20 20 20 20 5b 61 75 74 6f 76 61  pgcnt    [autova
4140: 63 75 75 6d 5f 6f 76 65 72 68 65 61 64 20 24 66  cuum_overhead $f
4150: 69 6c 65 5f 70 67 63 6e 74 20 24 70 61 67 65 53  ile_pgcnt $pageS
4160: 69 7a 65 5d 0a 73 65 74 20 61 76 5f 70 65 72 63  ize].set av_perc
4170: 65 6e 74 20 20 5b 70 65 72 63 65 6e 74 20 24 61  ent  [percent $a
4180: 76 5f 70 67 63 6e 74 20 24 66 69 6c 65 5f 70 67  v_pgcnt $file_pg
4190: 63 6e 74 5d 0a 0a 73 65 74 20 73 71 6c 20 7b 53  cnt]..set sql {S
41a0: 45 4c 45 43 54 20 73 75 6d 28 6c 65 61 66 5f 70  ELECT sum(leaf_p
41b0: 61 67 65 73 2b 69 6e 74 5f 70 61 67 65 73 2b 6f  ages+int_pages+o
41c0: 76 66 6c 5f 70 61 67 65 73 29 20 46 52 4f 4d 20  vfl_pages) FROM 
41d0: 73 70 61 63 65 5f 75 73 65 64 7d 0a 73 65 74 20  space_used}.set 
41e0: 69 6e 75 73 65 5f 70 67 63 6e 74 20 20 20 5b 65  inuse_pgcnt   [e
41f0: 78 70 72 20 77 69 64 65 28 5b 6d 65 6d 20 65 76  xpr wide([mem ev
4200: 61 6c 20 24 73 71 6c 5d 29 5d 0a 73 65 74 20 69  al $sql])].set i
4210: 6e 75 73 65 5f 70 65 72 63 65 6e 74 20 5b 70 65  nuse_percent [pe
4220: 72 63 65 6e 74 20 24 69 6e 75 73 65 5f 70 67 63  rcent $inuse_pgc
4230: 6e 74 20 24 66 69 6c 65 5f 70 67 63 6e 74 5d 0a  nt $file_pgcnt].
4240: 0a 73 65 74 20 66 72 65 65 5f 70 67 63 6e 74 20  .set free_pgcnt 
4250: 20 20 20 5b 65 78 70 72 20 7b 24 66 69 6c 65 5f     [expr {$file_
4260: 70 67 63 6e 74 2d 24 69 6e 75 73 65 5f 70 67 63  pgcnt-$inuse_pgc
4270: 6e 74 2d 24 61 76 5f 70 67 63 6e 74 7d 5d 0a 73  nt-$av_pgcnt}].s
4280: 65 74 20 66 72 65 65 5f 70 65 72 63 65 6e 74 20  et free_percent 
4290: 20 5b 70 65 72 63 65 6e 74 20 24 66 72 65 65 5f   [percent $free_
42a0: 70 67 63 6e 74 20 24 66 69 6c 65 5f 70 67 63 6e  pgcnt $file_pgcn
42b0: 74 5d 0a 73 65 74 20 66 72 65 65 5f 70 67 63 6e  t].set free_pgcn
42c0: 74 32 20 20 20 5b 64 62 20 6f 6e 65 20 7b 50 52  t2   [db one {PR
42d0: 41 47 4d 41 20 66 72 65 65 6c 69 73 74 5f 63 6f  AGMA freelist_co
42e0: 75 6e 74 7d 5d 0a 73 65 74 20 66 72 65 65 5f 70  unt}].set free_p
42f0: 65 72 63 65 6e 74 32 20 5b 70 65 72 63 65 6e 74  ercent2 [percent
4300: 20 24 66 72 65 65 5f 70 67 63 6e 74 32 20 24 66   $free_pgcnt2 $f
4310: 69 6c 65 5f 70 67 63 6e 74 5d 0a 0a 73 65 74 20  ile_pgcnt]..set 
4320: 66 69 6c 65 5f 70 67 63 6e 74 32 20 5b 65 78 70  file_pgcnt2 [exp
4330: 72 20 7b 24 69 6e 75 73 65 5f 70 67 63 6e 74 2b  r {$inuse_pgcnt+
4340: 24 66 72 65 65 5f 70 67 63 6e 74 32 2b 24 61 76  $free_pgcnt2+$av
4350: 5f 70 67 63 6e 74 7d 5d 0a 0a 73 65 74 20 6e 74  _pgcnt}]..set nt
4360: 61 62 6c 65 20 5b 64 62 20 65 76 61 6c 20 7b 53  able [db eval {S
4370: 45 4c 45 43 54 20 63 6f 75 6e 74 28 2a 29 2b 31  ELECT count(*)+1
4380: 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73   FROM sqlite_mas
4390: 74 65 72 20 57 48 45 52 45 20 74 79 70 65 3d 27  ter WHERE type='
43a0: 74 61 62 6c 65 27 7d 5d 0a 73 65 74 20 6e 69 6e  table'}].set nin
43b0: 64 65 78 20 5b 64 62 20 65 76 61 6c 20 7b 53 45  dex [db eval {SE
43c0: 4c 45 43 54 20 63 6f 75 6e 74 28 2a 29 20 46 52  LECT count(*) FR
43d0: 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72  OM sqlite_master
43e0: 20 57 48 45 52 45 20 74 79 70 65 3d 27 69 6e 64   WHERE type='ind
43f0: 65 78 27 7d 5d 0a 73 65 74 20 73 71 6c 20 7b 53  ex'}].set sql {S
4400: 45 4c 45 43 54 20 63 6f 75 6e 74 28 2a 29 20 46  ELECT count(*) F
4410: 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65  ROM sqlite_maste
4420: 72 20 57 48 45 52 45 20 6e 61 6d 65 20 4c 49 4b  r WHERE name LIK
4430: 45 20 27 73 71 6c 69 74 65 5f 61 75 74 6f 69 6e  E 'sqlite_autoin
4440: 64 65 78 25 27 7d 0a 73 65 74 20 6e 61 75 74 6f  dex%'}.set nauto
4450: 69 6e 64 65 78 20 5b 64 62 20 65 76 61 6c 20 24  index [db eval $
4460: 73 71 6c 5d 0a 73 65 74 20 6e 6d 61 6e 69 6e 64  sql].set nmanind
4470: 65 78 20 5b 65 78 70 72 20 7b 24 6e 69 6e 64 65  ex [expr {$ninde
4480: 78 2d 24 6e 61 75 74 6f 69 6e 64 65 78 7d 5d 0a  x-$nautoindex}].
4490: 0a 23 20 73 65 74 20 74 6f 74 61 6c 5f 70 61 79  .# set total_pay
44a0: 6c 6f 61 64 20 5b 6d 65 6d 20 65 76 61 6c 20 22  load [mem eval "
44b0: 53 45 4c 45 43 54 20 73 75 6d 28 70 61 79 6c 6f  SELECT sum(paylo
44c0: 61 64 29 20 46 52 4f 4d 20 73 70 61 63 65 5f 75  ad) FROM space_u
44d0: 73 65 64 22 5d 0a 73 65 74 20 75 73 65 72 5f 70  sed"].set user_p
44e0: 61 79 6c 6f 61 64 20 5b 6d 65 6d 20 6f 6e 65 20  ayload [mem one 
44f0: 7b 53 45 4c 45 43 54 20 69 6e 74 28 73 75 6d 28  {SELECT int(sum(
4500: 70 61 79 6c 6f 61 64 29 29 20 46 52 4f 4d 20 73  payload)) FROM s
4510: 70 61 63 65 5f 75 73 65 64 0a 20 20 20 20 20 57  pace_used.     W
4520: 48 45 52 45 20 4e 4f 54 20 69 73 5f 69 6e 64 65  HERE NOT is_inde
4530: 78 20 41 4e 44 20 6e 61 6d 65 20 4e 4f 54 20 4c  x AND name NOT L
4540: 49 4b 45 20 27 73 71 6c 69 74 65 5f 6d 61 73 74  IKE 'sqlite_mast
4550: 65 72 27 7d 5d 0a 73 65 74 20 75 73 65 72 5f 70  er'}].set user_p
4560: 65 72 63 65 6e 74 20 5b 70 65 72 63 65 6e 74 20  ercent [percent 
4570: 24 75 73 65 72 5f 70 61 79 6c 6f 61 64 20 24 66  $user_payload $f
4580: 69 6c 65 5f 62 79 74 65 73 5d 0a 0a 23 20 4f 75  ile_bytes]..# Ou
4590: 74 70 75 74 20 74 68 65 20 73 75 6d 6d 61 72 79  tput the summary
45a0: 20 73 74 61 74 69 73 74 69 63 73 20 63 61 6c 63   statistics calc
45b0: 75 6c 61 74 65 64 20 61 62 6f 76 65 2e 0a 23 0a  ulated above..#.
45c0: 70 75 74 73 20 22 2f 2a 2a 20 44 69 73 6b 2d 53  puts "/** Disk-S
45d0: 70 61 63 65 20 55 74 69 6c 69 7a 61 74 69 6f 6e  pace Utilization
45e0: 20 52 65 70 6f 72 74 20 46 6f 72 20 24 72 6f 6f   Report For $roo
45f0: 74 5f 66 69 6c 65 6e 61 6d 65 22 0a 70 75 74 73  t_filename".puts
4600: 20 22 22 0a 73 74 61 74 6c 69 6e 65 20 7b 50 61   "".statline {Pa
4610: 67 65 20 73 69 7a 65 20 69 6e 20 62 79 74 65 73  ge size in bytes
4620: 7d 20 24 70 61 67 65 53 69 7a 65 0a 73 74 61 74  } $pageSize.stat
4630: 6c 69 6e 65 20 7b 50 61 67 65 73 20 69 6e 20 74  line {Pages in t
4640: 68 65 20 77 68 6f 6c 65 20 66 69 6c 65 20 28 6d  he whole file (m
4650: 65 61 73 75 72 65 64 29 7d 20 24 66 69 6c 65 5f  easured)} $file_
4660: 70 67 63 6e 74 0a 73 74 61 74 6c 69 6e 65 20 7b  pgcnt.statline {
4670: 50 61 67 65 73 20 69 6e 20 74 68 65 20 77 68 6f  Pages in the who
4680: 6c 65 20 66 69 6c 65 20 28 63 61 6c 63 75 6c 61  le file (calcula
4690: 74 65 64 29 7d 20 24 66 69 6c 65 5f 70 67 63 6e  ted)} $file_pgcn
46a0: 74 32 0a 73 74 61 74 6c 69 6e 65 20 7b 50 61 67  t2.statline {Pag
46b0: 65 73 20 74 68 61 74 20 73 74 6f 72 65 20 64 61  es that store da
46c0: 74 61 7d 20 24 69 6e 75 73 65 5f 70 67 63 6e 74  ta} $inuse_pgcnt
46d0: 20 24 69 6e 75 73 65 5f 70 65 72 63 65 6e 74 0a   $inuse_percent.
46e0: 73 74 61 74 6c 69 6e 65 20 7b 50 61 67 65 73 20  statline {Pages 
46f0: 6f 6e 20 74 68 65 20 66 72 65 65 6c 69 73 74 20  on the freelist 
4700: 28 70 65 72 20 68 65 61 64 65 72 29 7d 20 24 66  (per header)} $f
4710: 72 65 65 5f 70 67 63 6e 74 32 20 24 66 72 65 65  ree_pgcnt2 $free
4720: 5f 70 65 72 63 65 6e 74 32 0a 73 74 61 74 6c 69  _percent2.statli
4730: 6e 65 20 7b 50 61 67 65 73 20 6f 6e 20 74 68 65  ne {Pages on the
4740: 20 66 72 65 65 6c 69 73 74 20 28 63 61 6c 63 75   freelist (calcu
4750: 6c 61 74 65 64 29 7d 20 24 66 72 65 65 5f 70 67  lated)} $free_pg
4760: 63 6e 74 20 24 66 72 65 65 5f 70 65 72 63 65 6e  cnt $free_percen
4770: 74 0a 73 74 61 74 6c 69 6e 65 20 7b 50 61 67 65  t.statline {Page
4780: 73 20 6f 66 20 61 75 74 6f 2d 76 61 63 75 75 6d  s of auto-vacuum
4790: 20 6f 76 65 72 68 65 61 64 7d 20 24 61 76 5f 70   overhead} $av_p
47a0: 67 63 6e 74 20 24 61 76 5f 70 65 72 63 65 6e 74  gcnt $av_percent
47b0: 0a 73 74 61 74 6c 69 6e 65 20 7b 4e 75 6d 62 65  .statline {Numbe
47c0: 72 20 6f 66 20 74 61 62 6c 65 73 20 69 6e 20 74  r of tables in t
47d0: 68 65 20 64 61 74 61 62 61 73 65 7d 20 24 6e 74  he database} $nt
47e0: 61 62 6c 65 0a 73 74 61 74 6c 69 6e 65 20 7b 4e  able.statline {N
47f0: 75 6d 62 65 72 20 6f 66 20 69 6e 64 69 63 65 73  umber of indices
4800: 7d 20 24 6e 69 6e 64 65 78 0a 73 74 61 74 6c 69  } $nindex.statli
4810: 6e 65 20 7b 4e 75 6d 62 65 72 20 6f 66 20 64 65  ne {Number of de
4820: 66 69 6e 65 64 20 69 6e 64 69 63 65 73 7d 20 24  fined indices} $
4830: 6e 6d 61 6e 69 6e 64 65 78 0a 73 74 61 74 6c 69  nmanindex.statli
4840: 6e 65 20 7b 4e 75 6d 62 65 72 20 6f 66 20 69 6d  ne {Number of im
4850: 70 6c 69 65 64 20 69 6e 64 69 63 65 73 7d 20 24  plied indices} $
4860: 6e 61 75 74 6f 69 6e 64 65 78 0a 69 66 20 7b 24  nautoindex.if {$
4870: 69 73 43 6f 6d 70 72 65 73 73 65 64 7d 20 7b 0a  isCompressed} {.
4880: 20 20 73 74 61 74 6c 69 6e 65 20 7b 53 69 7a 65    statline {Size
4890: 20 6f 66 20 75 6e 63 6f 6d 70 72 65 73 73 65 64   of uncompressed
48a0: 20 63 6f 6e 74 65 6e 74 20 69 6e 20 62 79 74 65   content in byte
48b0: 73 7d 20 24 66 69 6c 65 5f 62 79 74 65 73 0a 20  s} $file_bytes. 
48c0: 20 73 65 74 20 65 66 66 69 63 69 65 6e 63 79 20   set efficiency 
48d0: 5b 70 65 72 63 65 6e 74 20 24 74 72 75 65 5f 66  [percent $true_f
48e0: 69 6c 65 5f 73 69 7a 65 20 24 66 69 6c 65 5f 62  ile_size $file_b
48f0: 79 74 65 73 5d 0a 20 20 73 74 61 74 6c 69 6e 65  ytes].  statline
4900: 20 7b 53 69 7a 65 20 6f 66 20 63 6f 6d 70 72 65   {Size of compre
4910: 73 73 65 64 20 66 69 6c 65 20 6f 6e 20 64 69 73  ssed file on dis
4920: 6b 7d 20 24 74 72 75 65 5f 66 69 6c 65 5f 73 69  k} $true_file_si
4930: 7a 65 20 24 65 66 66 69 63 69 65 6e 63 79 0a 7d  ze $efficiency.}
4940: 20 65 6c 73 65 20 7b 0a 20 20 73 74 61 74 6c 69   else {.  statli
4950: 6e 65 20 7b 53 69 7a 65 20 6f 66 20 74 68 65 20  ne {Size of the 
4960: 66 69 6c 65 20 69 6e 20 62 79 74 65 73 7d 20 24  file in bytes} $
4970: 66 69 6c 65 5f 62 79 74 65 73 0a 7d 0a 73 74 61  file_bytes.}.sta
4980: 74 6c 69 6e 65 20 7b 42 79 74 65 73 20 6f 66 20  tline {Bytes of 
4990: 75 73 65 72 20 70 61 79 6c 6f 61 64 20 73 74 6f  user payload sto
49a0: 72 65 64 7d 20 24 75 73 65 72 5f 70 61 79 6c 6f  red} $user_paylo
49b0: 61 64 20 24 75 73 65 72 5f 70 65 72 63 65 6e 74  ad $user_percent
49c0: 0a 0a 23 20 4f 75 74 70 75 74 20 74 61 62 6c 65  ..# Output table
49d0: 20 72 61 6e 6b 69 6e 67 73 0a 23 0a 70 75 74 73   rankings.#.puts
49e0: 20 22 22 0a 74 69 74 6c 65 6c 69 6e 65 20 22 50   "".titleline "P
49f0: 61 67 65 20 63 6f 75 6e 74 73 20 66 6f 72 20 61  age counts for a
4a00: 6c 6c 20 74 61 62 6c 65 73 20 77 69 74 68 20 74  ll tables with t
4a10: 68 65 69 72 20 69 6e 64 69 63 65 73 22 0a 70 75  heir indices".pu
4a20: 74 73 20 22 22 0a 6d 65 6d 20 65 76 61 6c 20 7b  ts "".mem eval {
4a30: 53 45 4c 45 43 54 20 74 62 6c 6e 61 6d 65 2c 20  SELECT tblname, 
4a40: 63 6f 75 6e 74 28 2a 29 20 41 53 20 63 6e 74 2c  count(*) AS cnt,
4a50: 20 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20   .              
4a60: 69 6e 74 28 73 75 6d 28 69 6e 74 5f 70 61 67 65  int(sum(int_page
4a70: 73 2b 6c 65 61 66 5f 70 61 67 65 73 2b 6f 76 66  s+leaf_pages+ovf
4a80: 6c 5f 70 61 67 65 73 29 29 20 41 53 20 73 69 7a  l_pages)) AS siz
4a90: 65 0a 20 20 20 20 20 20 20 20 20 20 46 52 4f 4d  e.          FROM
4aa0: 20 73 70 61 63 65 5f 75 73 65 64 20 47 52 4f 55   space_used GROU
4ab0: 50 20 42 59 20 74 62 6c 6e 61 6d 65 20 4f 52 44  P BY tblname ORD
4ac0: 45 52 20 42 59 20 73 69 7a 65 2b 30 20 44 45 53  ER BY size+0 DES
4ad0: 43 2c 20 74 62 6c 6e 61 6d 65 7d 20 7b 7d 20 7b  C, tblname} {} {
4ae0: 0a 20 20 73 74 61 74 6c 69 6e 65 20 5b 73 74 72  .  statline [str
4af0: 69 6e 67 20 74 6f 75 70 70 65 72 20 24 74 62 6c  ing toupper $tbl
4b00: 6e 61 6d 65 5d 20 24 73 69 7a 65 20 5b 70 65 72  name] $size [per
4b10: 63 65 6e 74 20 24 73 69 7a 65 20 24 66 69 6c 65  cent $size $file
4b20: 5f 70 67 63 6e 74 5d 0a 7d 0a 70 75 74 73 20 22  _pgcnt].}.puts "
4b30: 22 0a 74 69 74 6c 65 6c 69 6e 65 20 22 50 61 67  ".titleline "Pag
4b40: 65 20 63 6f 75 6e 74 73 20 66 6f 72 20 61 6c 6c  e counts for all
4b50: 20 74 61 62 6c 65 73 20 61 6e 64 20 69 6e 64 69   tables and indi
4b60: 63 65 73 20 73 65 70 61 72 61 74 65 6c 79 22 0a  ces separately".
4b70: 70 75 74 73 20 22 22 0a 6d 65 6d 20 65 76 61 6c  puts "".mem eval
4b80: 20 7b 0a 20 20 53 45 4c 45 43 54 0a 20 20 20 20   {.  SELECT.    
4b90: 20 20 20 75 70 70 65 72 28 6e 61 6d 65 29 20 41     upper(name) A
4ba0: 53 20 6e 6d 2c 0a 20 20 20 20 20 20 20 69 6e 74  S nm,.       int
4bb0: 28 69 6e 74 5f 70 61 67 65 73 2b 6c 65 61 66 5f  (int_pages+leaf_
4bc0: 70 61 67 65 73 2b 6f 76 66 6c 5f 70 61 67 65 73  pages+ovfl_pages
4bd0: 29 20 41 53 20 73 69 7a 65 0a 20 20 20 20 46 52  ) AS size.    FR
4be0: 4f 4d 20 73 70 61 63 65 5f 75 73 65 64 0a 20 20  OM space_used.  
4bf0: 20 4f 52 44 45 52 20 42 59 20 73 69 7a 65 2b 30   ORDER BY size+0
4c00: 20 44 45 53 43 2c 20 6e 61 6d 65 7d 20 7b 7d 20   DESC, name} {} 
4c10: 7b 0a 20 20 73 74 61 74 6c 69 6e 65 20 24 6e 6d  {.  statline $nm
4c20: 20 24 73 69 7a 65 20 5b 70 65 72 63 65 6e 74 20   $size [percent 
4c30: 24 73 69 7a 65 20 24 66 69 6c 65 5f 70 67 63 6e  $size $file_pgcn
4c40: 74 5d 0a 7d 0a 69 66 20 7b 24 69 73 43 6f 6d 70  t].}.if {$isComp
4c50: 72 65 73 73 65 64 7d 20 7b 0a 20 20 70 75 74 73  ressed} {.  puts
4c60: 20 22 22 0a 20 20 74 69 74 6c 65 6c 69 6e 65 20   "".  titleline 
4c70: 22 42 79 74 65 73 20 6f 66 20 64 69 73 6b 20 73  "Bytes of disk s
4c80: 70 61 63 65 20 75 73 65 64 20 61 66 74 65 72 20  pace used after 
4c90: 63 6f 6d 70 72 65 73 73 69 6f 6e 22 0a 20 20 70  compression".  p
4ca0: 75 74 73 20 22 22 0a 20 20 73 65 74 20 63 73 75  uts "".  set csu
4cb0: 6d 20 30 0a 20 20 6d 65 6d 20 65 76 61 6c 20 7b  m 0.  mem eval {
4cc0: 53 45 4c 45 43 54 20 74 62 6c 6e 61 6d 65 2c 0a  SELECT tblname,.
4cd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4ce0: 20 20 69 6e 74 28 73 75 6d 28 63 6f 6d 70 72 65    int(sum(compre
4cf0: 73 73 65 64 5f 73 69 7a 65 29 29 20 2b 0a 20 20  ssed_size)) +.  
4d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4d10: 20 20 20 20 20 20 20 24 63 6f 6d 70 72 65 73 73         $compress
4d20: 4f 76 65 72 68 65 61 64 2a 73 75 6d 28 69 6e 74  Overhead*sum(int
4d30: 5f 70 61 67 65 73 2b 6c 65 61 66 5f 70 61 67 65  _pages+leaf_page
4d40: 73 2b 6f 76 66 6c 5f 70 61 67 65 73 29 0a 20 20  s+ovfl_pages).  
4d50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4d60: 20 20 20 20 20 20 41 53 20 63 73 69 7a 65 0a 20        AS csize. 
4d70: 20 20 20 20 20 20 20 20 20 46 52 4f 4d 20 73 70           FROM sp
4d80: 61 63 65 5f 75 73 65 64 20 47 52 4f 55 50 20 42  ace_used GROUP B
4d90: 59 20 74 62 6c 6e 61 6d 65 20 4f 52 44 45 52 20  Y tblname ORDER 
4da0: 42 59 20 63 73 69 7a 65 2b 30 20 44 45 53 43 2c  BY csize+0 DESC,
4db0: 20 74 62 6c 6e 61 6d 65 7d 20 7b 7d 20 7b 0a 20   tblname} {} {. 
4dc0: 20 20 20 69 6e 63 72 20 63 73 75 6d 20 24 63 73     incr csum $cs
4dd0: 69 7a 65 0a 20 20 20 20 73 74 61 74 6c 69 6e 65  ize.    statline
4de0: 20 5b 73 74 72 69 6e 67 20 74 6f 75 70 70 65 72   [string toupper
4df0: 20 24 74 62 6c 6e 61 6d 65 5d 20 24 63 73 69 7a   $tblname] $csiz
4e00: 65 20 5b 70 65 72 63 65 6e 74 20 24 63 73 69 7a  e [percent $csiz
4e10: 65 20 24 74 72 75 65 5f 66 69 6c 65 5f 73 69 7a  e $true_file_siz
4e20: 65 5d 0a 20 20 7d 0a 20 20 73 65 74 20 6f 76 65  e].  }.  set ove
4e30: 72 68 65 61 64 20 5b 65 78 70 72 20 7b 24 74 72  rhead [expr {$tr
4e40: 75 65 5f 66 69 6c 65 5f 73 69 7a 65 20 2d 20 24  ue_file_size - $
4e50: 63 73 75 6d 7d 5d 0a 20 20 69 66 20 7b 24 6f 76  csum}].  if {$ov
4e60: 65 72 68 65 61 64 3e 30 7d 20 7b 0a 20 20 20 20  erhead>0} {.    
4e70: 73 74 61 74 6c 69 6e 65 20 7b 48 65 61 64 65 72  statline {Header
4e80: 20 61 6e 64 20 66 72 65 65 20 73 70 61 63 65 7d   and free space}
4e90: 20 24 6f 76 65 72 68 65 61 64 20 5b 70 65 72 63   $overhead [perc
4ea0: 65 6e 74 20 24 6f 76 65 72 68 65 61 64 20 24 74  ent $overhead $t
4eb0: 72 75 65 5f 66 69 6c 65 5f 73 69 7a 65 5d 0a 20  rue_file_size]. 
4ec0: 20 7d 0a 7d 0a 0a 23 20 4f 75 74 70 75 74 20 73   }.}..# Output s
4ed0: 75 62 72 65 70 6f 72 74 73 0a 23 0a 69 66 20 7b  ubreports.#.if {
4ee0: 24 6e 69 6e 64 65 78 3e 30 7d 20 7b 0a 20 20 73  $nindex>0} {.  s
4ef0: 75 62 72 65 70 6f 72 74 20 7b 41 6c 6c 20 74 61  ubreport {All ta
4f00: 62 6c 65 73 20 61 6e 64 20 69 6e 64 69 63 65 73  bles and indices
4f10: 7d 20 31 20 30 0a 7d 0a 73 75 62 72 65 70 6f 72  } 1 0.}.subrepor
4f20: 74 20 7b 41 6c 6c 20 74 61 62 6c 65 73 7d 20 7b  t {All tables} {
4f30: 4e 4f 54 20 69 73 5f 69 6e 64 65 78 7d 20 30 0a  NOT is_index} 0.
4f40: 69 66 20 7b 24 6e 69 6e 64 65 78 3e 30 7d 20 7b  if {$nindex>0} {
4f50: 0a 20 20 73 75 62 72 65 70 6f 72 74 20 7b 41 6c  .  subreport {Al
4f60: 6c 20 69 6e 64 69 63 65 73 7d 20 7b 69 73 5f 69  l indices} {is_i
4f70: 6e 64 65 78 7d 20 30 0a 7d 0a 66 6f 72 65 61 63  ndex} 0.}.foreac
4f80: 68 20 74 62 6c 20 5b 6d 65 6d 20 65 76 61 6c 20  h tbl [mem eval 
4f90: 7b 53 45 4c 45 43 54 20 6e 61 6d 65 20 46 52 4f  {SELECT name FRO
4fa0: 4d 20 73 70 61 63 65 5f 75 73 65 64 20 57 48 45  M space_used WHE
4fb0: 52 45 20 4e 4f 54 20 69 73 5f 69 6e 64 65 78 0a  RE NOT is_index.
4fc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4fd0: 20 20 20 20 20 20 20 4f 52 44 45 52 20 42 59 20         ORDER BY 
4fe0: 6e 61 6d 65 7d 5d 20 7b 0a 20 20 73 65 74 20 71  name}] {.  set q
4ff0: 6e 20 5b 71 75 6f 74 65 20 24 74 62 6c 5d 0a 20  n [quote $tbl]. 
5000: 20 73 65 74 20 6e 61 6d 65 20 5b 73 74 72 69 6e   set name [strin
5010: 67 20 74 6f 75 70 70 65 72 20 24 74 62 6c 5d 0a  g toupper $tbl].
5020: 20 20 73 65 74 20 6e 20 5b 6d 65 6d 20 65 76 61    set n [mem eva
5030: 6c 20 7b 53 45 4c 45 43 54 20 63 6f 75 6e 74 28  l {SELECT count(
5040: 2a 29 20 46 52 4f 4d 20 73 70 61 63 65 5f 75 73  *) FROM space_us
5050: 65 64 20 57 48 45 52 45 20 74 62 6c 6e 61 6d 65  ed WHERE tblname
5060: 3d 24 74 62 6c 7d 5d 0a 20 20 69 66 20 7b 24 6e  =$tbl}].  if {$n
5070: 3e 31 7d 20 7b 0a 20 20 20 20 73 65 74 20 69 64  >1} {.    set id
5080: 78 6c 69 73 74 20 5b 6d 65 6d 20 65 76 61 6c 20  xlist [mem eval 
5090: 22 53 45 4c 45 43 54 20 6e 61 6d 65 20 46 52 4f  "SELECT name FRO
50a0: 4d 20 73 70 61 63 65 5f 75 73 65 64 0a 20 20 20  M space_used.   
50b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
50c0: 20 20 20 20 20 20 20 20 20 57 48 45 52 45 20 74           WHERE t
50d0: 62 6c 6e 61 6d 65 3d 27 24 71 6e 27 20 41 4e 44  blname='$qn' AND
50e0: 20 69 73 5f 69 6e 64 65 78 0a 20 20 20 20 20 20   is_index.      
50f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5100: 20 20 20 20 20 20 4f 52 44 45 52 20 42 59 20 31        ORDER BY 1
5110: 22 5d 0a 20 20 20 20 73 75 62 72 65 70 6f 72 74  "].    subreport
5120: 20 22 54 61 62 6c 65 20 24 6e 61 6d 65 20 61 6e   "Table $name an
5130: 64 20 61 6c 6c 20 69 74 73 20 69 6e 64 69 63 65  d all its indice
5140: 73 22 20 22 74 62 6c 6e 61 6d 65 3d 27 24 71 6e  s" "tblname='$qn
5150: 27 22 20 30 0a 20 20 20 20 73 75 62 72 65 70 6f  '" 0.    subrepo
5160: 72 74 20 22 54 61 62 6c 65 20 24 6e 61 6d 65 20  rt "Table $name 
5170: 77 2f 6f 20 61 6e 79 20 69 6e 64 69 63 65 73 22  w/o any indices"
5180: 20 22 6e 61 6d 65 3d 27 24 71 6e 27 22 20 31 0a   "name='$qn'" 1.
5190: 20 20 20 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68      if {[llength
51a0: 20 24 69 64 78 6c 69 73 74 5d 3e 31 7d 20 7b 0a   $idxlist]>1} {.
51b0: 20 20 20 20 20 20 73 75 62 72 65 70 6f 72 74 20        subreport 
51c0: 22 49 6e 64 69 63 65 73 20 6f 66 20 74 61 62 6c  "Indices of tabl
51d0: 65 20 24 6e 61 6d 65 22 20 22 74 62 6c 6e 61 6d  e $name" "tblnam
51e0: 65 3d 27 24 71 6e 27 20 41 4e 44 20 69 73 5f 69  e='$qn' AND is_i
51f0: 6e 64 65 78 22 20 30 0a 20 20 20 20 7d 0a 20 20  ndex" 0.    }.  
5200: 20 20 66 6f 72 65 61 63 68 20 69 64 78 20 24 69    foreach idx $i
5210: 64 78 6c 69 73 74 20 7b 0a 20 20 20 20 20 20 73  dxlist {.      s
5220: 65 74 20 71 69 64 78 20 5b 71 75 6f 74 65 20 24  et qidx [quote $
5230: 69 64 78 5d 0a 20 20 20 20 20 20 73 75 62 72 65  idx].      subre
5240: 70 6f 72 74 20 22 49 6e 64 65 78 20 5b 73 74 72  port "Index [str
5250: 69 6e 67 20 74 6f 75 70 70 65 72 20 24 69 64 78  ing toupper $idx
5260: 5d 20 6f 66 20 74 61 62 6c 65 20 24 6e 61 6d 65  ] of table $name
5270: 22 20 22 6e 61 6d 65 3d 27 24 71 69 64 78 27 22  " "name='$qidx'"
5280: 20 31 0a 20 20 20 20 7d 0a 20 20 7d 20 65 6c 73   1.    }.  } els
5290: 65 20 7b 0a 20 20 20 20 73 75 62 72 65 70 6f 72  e {.    subrepor
52a0: 74 20 22 54 61 62 6c 65 20 24 6e 61 6d 65 22 20  t "Table $name" 
52b0: 22 6e 61 6d 65 3d 27 24 71 6e 27 22 20 31 0a 20  "name='$qn'" 1. 
52c0: 20 7d 0a 7d 0a 0a 23 20 4f 75 74 70 75 74 20 69   }.}..# Output i
52d0: 6e 73 74 72 75 63 74 69 6f 6e 73 20 6f 6e 20 77  nstructions on w
52e0: 68 61 74 20 74 68 65 20 6e 75 6d 62 65 72 73 20  hat the numbers 
52f0: 61 62 6f 76 65 20 6d 65 61 6e 2e 0a 23 0a 70 75  above mean..#.pu
5300: 74 73 20 22 22 0a 74 69 74 6c 65 6c 69 6e 65 20  ts "".titleline 
5310: 44 65 66 69 6e 69 74 69 6f 6e 73 0a 70 75 74 73  Definitions.puts
5320: 20 7b 0a 50 61 67 65 20 73 69 7a 65 20 69 6e 20   {.Page size in 
5330: 62 79 74 65 73 0a 0a 20 20 20 20 54 68 65 20 6e  bytes..    The n
5340: 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 69  umber of bytes i
5350: 6e 20 61 20 73 69 6e 67 6c 65 20 70 61 67 65 20  n a single page 
5360: 6f 66 20 74 68 65 20 64 61 74 61 62 61 73 65 20  of the database 
5370: 66 69 6c 65 2e 20 20 0a 20 20 20 20 55 73 75 61  file.  .    Usua
5380: 6c 6c 79 20 31 30 32 34 2e 0a 0a 4e 75 6d 62 65  lly 1024...Numbe
5390: 72 20 6f 66 20 70 61 67 65 73 20 69 6e 20 74 68  r of pages in th
53a0: 65 20 77 68 6f 6c 65 20 66 69 6c 65 0a 7d 0a 70  e whole file.}.p
53b0: 75 74 73 20 22 20 20 20 20 54 68 65 20 6e 75 6d  uts "    The num
53c0: 62 65 72 20 6f 66 20 24 70 61 67 65 53 69 7a 65  ber of $pageSize
53d0: 2d 62 79 74 65 20 70 61 67 65 73 20 74 68 61 74  -byte pages that
53e0: 20 67 6f 20 69 6e 74 6f 20 66 6f 72 6d 69 6e 67   go into forming
53f0: 20 74 68 65 20 63 6f 6d 70 6c 65 74 65 0a 20 20   the complete.  
5400: 20 20 64 61 74 61 62 61 73 65 22 0a 70 75 74 73    database".puts
5410: 20 7b 0a 50 61 67 65 73 20 74 68 61 74 20 73 74   {.Pages that st
5420: 6f 72 65 20 64 61 74 61 0a 0a 20 20 20 20 54 68  ore data..    Th
5430: 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65  e number of page
5440: 73 20 74 68 61 74 20 73 74 6f 72 65 20 64 61 74  s that store dat
5450: 61 2c 20 65 69 74 68 65 72 20 61 73 20 70 72 69  a, either as pri
5460: 6d 61 72 79 20 42 2a 54 72 65 65 20 70 61 67 65  mary B*Tree page
5470: 73 20 6f 72 0a 20 20 20 20 61 73 20 6f 76 65 72  s or.    as over
5480: 66 6c 6f 77 20 70 61 67 65 73 2e 20 20 54 68 65  flow pages.  The
5490: 20 6e 75 6d 62 65 72 20 61 74 20 74 68 65 20 72   number at the r
54a0: 69 67 68 74 20 69 73 20 74 68 65 20 64 61 74 61  ight is the data
54b0: 20 70 61 67 65 73 20 64 69 76 69 64 65 64 20 62   pages divided b
54c0: 79 0a 20 20 20 20 74 68 65 20 74 6f 74 61 6c 20  y.    the total 
54d0: 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  number of pages 
54e0: 69 6e 20 74 68 65 20 66 69 6c 65 2e 0a 0a 50 61  in the file...Pa
54f0: 67 65 73 20 6f 6e 20 74 68 65 20 66 72 65 65 6c  ges on the freel
5500: 69 73 74 0a 0a 20 20 20 20 54 68 65 20 6e 75 6d  ist..    The num
5510: 62 65 72 20 6f 66 20 70 61 67 65 73 20 74 68 61  ber of pages tha
5520: 74 20 61 72 65 20 6e 6f 74 20 63 75 72 72 65 6e  t are not curren
5530: 74 6c 79 20 69 6e 20 75 73 65 20 62 75 74 20 61  tly in use but a
5540: 72 65 20 72 65 73 65 72 76 65 64 20 66 6f 72 0a  re reserved for.
5550: 20 20 20 20 66 75 74 75 72 65 20 75 73 65 2e 20      future use. 
5560: 20 54 68 65 20 70 65 72 63 65 6e 74 61 67 65 20   The percentage 
5570: 61 74 20 74 68 65 20 72 69 67 68 74 20 69 73 20  at the right is 
5580: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 66 72  the number of fr
5590: 65 65 6c 69 73 74 20 70 61 67 65 73 0a 20 20 20  eelist pages.   
55a0: 20 64 69 76 69 64 65 64 20 62 79 20 74 68 65 20   divided by the 
55b0: 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20  total number of 
55c0: 70 61 67 65 73 20 69 6e 20 74 68 65 20 66 69 6c  pages in the fil
55d0: 65 2e 0a 0a 50 61 67 65 73 20 6f 66 20 61 75 74  e...Pages of aut
55e0: 6f 2d 76 61 63 75 75 6d 20 6f 76 65 72 68 65 61  o-vacuum overhea
55f0: 64 0a 0a 20 20 20 20 54 68 65 20 6e 75 6d 62 65  d..    The numbe
5600: 72 20 6f 66 20 70 61 67 65 73 20 74 68 61 74 20  r of pages that 
5610: 73 74 6f 72 65 20 64 61 74 61 20 75 73 65 64 20  store data used 
5620: 62 79 20 74 68 65 20 64 61 74 61 62 61 73 65 20  by the database 
5630: 74 6f 20 66 61 63 69 6c 69 74 61 74 65 0a 20 20  to facilitate.  
5640: 20 20 61 75 74 6f 2d 76 61 63 75 75 6d 2e 20 54    auto-vacuum. T
5650: 68 69 73 20 69 73 20 7a 65 72 6f 20 66 6f 72 20  his is zero for 
5660: 64 61 74 61 62 61 73 65 73 20 74 68 61 74 20 64  databases that d
5670: 6f 20 6e 6f 74 20 73 75 70 70 6f 72 74 20 61 75  o not support au
5680: 74 6f 2d 76 61 63 75 75 6d 2e 0a 0a 4e 75 6d 62  to-vacuum...Numb
5690: 65 72 20 6f 66 20 74 61 62 6c 65 73 20 69 6e 20  er of tables in 
56a0: 74 68 65 20 64 61 74 61 62 61 73 65 0a 0a 20 20  the database..  
56b0: 20 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66 20    The number of 
56c0: 74 61 62 6c 65 73 20 69 6e 20 74 68 65 20 64 61  tables in the da
56d0: 74 61 62 61 73 65 2c 20 69 6e 63 6c 75 64 69 6e  tabase, includin
56e0: 67 20 74 68 65 20 53 51 4c 49 54 45 5f 4d 41 53  g the SQLITE_MAS
56f0: 54 45 52 20 74 61 62 6c 65 0a 20 20 20 20 75 73  TER table.    us
5700: 65 64 20 74 6f 20 73 74 6f 72 65 20 73 63 68 65  ed to store sche
5710: 6d 61 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 2e 0a  ma information..
5720: 0a 4e 75 6d 62 65 72 20 6f 66 20 69 6e 64 69 63  .Number of indic
5730: 65 73 0a 0a 20 20 20 20 54 68 65 20 74 6f 74 61  es..    The tota
5740: 6c 20 6e 75 6d 62 65 72 20 6f 66 20 69 6e 64 69  l number of indi
5750: 63 65 73 20 69 6e 20 74 68 65 20 64 61 74 61 62  ces in the datab
5760: 61 73 65 2e 0a 0a 4e 75 6d 62 65 72 20 6f 66 20  ase...Number of 
5770: 64 65 66 69 6e 65 64 20 69 6e 64 69 63 65 73 0a  defined indices.
5780: 0a 20 20 20 20 54 68 65 20 6e 75 6d 62 65 72 20  .    The number 
5790: 6f 66 20 69 6e 64 69 63 65 73 20 63 72 65 61 74  of indices creat
57a0: 65 64 20 75 73 69 6e 67 20 61 6e 20 65 78 70 6c  ed using an expl
57b0: 69 63 69 74 20 43 52 45 41 54 45 20 49 4e 44 45  icit CREATE INDE
57c0: 58 20 73 74 61 74 65 6d 65 6e 74 2e 0a 0a 4e 75  X statement...Nu
57d0: 6d 62 65 72 20 6f 66 20 69 6d 70 6c 69 65 64 20  mber of implied 
57e0: 69 6e 64 69 63 65 73 0a 0a 20 20 20 20 54 68 65  indices..    The
57f0: 20 6e 75 6d 62 65 72 20 6f 66 20 69 6e 64 69 63   number of indic
5800: 65 73 20 75 73 65 64 20 74 6f 20 69 6d 70 6c 65  es used to imple
5810: 6d 65 6e 74 20 50 52 49 4d 41 52 59 20 4b 45 59  ment PRIMARY KEY
5820: 20 6f 72 20 55 4e 49 51 55 45 20 63 6f 6e 73 74   or UNIQUE const
5830: 72 61 69 6e 74 73 0a 20 20 20 20 6f 6e 20 74 61  raints.    on ta
5840: 62 6c 65 73 2e 0a 0a 53 69 7a 65 20 6f 66 20 74  bles...Size of t
5850: 68 65 20 66 69 6c 65 20 69 6e 20 62 79 74 65 73  he file in bytes
5860: 0a 0a 20 20 20 20 54 68 65 20 74 6f 74 61 6c 20  ..    The total 
5870: 61 6d 6f 75 6e 74 20 6f 66 20 64 69 73 6b 20 73  amount of disk s
5880: 70 61 63 65 20 75 73 65 64 20 62 79 20 74 68 65  pace used by the
5890: 20 65 6e 74 69 72 65 20 64 61 74 61 62 61 73 65   entire database
58a0: 20 66 69 6c 65 73 2e 0a 0a 42 79 74 65 73 20 6f   files...Bytes o
58b0: 66 20 75 73 65 72 20 70 61 79 6c 6f 61 64 20 73  f user payload s
58c0: 74 6f 72 65 64 0a 0a 20 20 20 20 54 68 65 20 74  tored..    The t
58d0: 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 62  otal number of b
58e0: 79 74 65 73 20 6f 66 20 75 73 65 72 20 70 61 79  ytes of user pay
58f0: 6c 6f 61 64 20 73 74 6f 72 65 64 20 69 6e 20 74  load stored in t
5900: 68 65 20 64 61 74 61 62 61 73 65 2e 20 54 68 65  he database. The
5910: 0a 20 20 20 20 73 63 68 65 6d 61 20 69 6e 66 6f  .    schema info
5920: 72 6d 61 74 69 6f 6e 20 69 6e 20 74 68 65 20 53  rmation in the S
5930: 51 4c 49 54 45 5f 4d 41 53 54 45 52 20 74 61 62  QLITE_MASTER tab
5940: 6c 65 20 69 73 20 6e 6f 74 20 63 6f 75 6e 74 65  le is not counte
5950: 64 20 77 68 65 6e 0a 20 20 20 20 63 6f 6d 70 75  d when.    compu
5960: 74 69 6e 67 20 74 68 69 73 20 6e 75 6d 62 65 72  ting this number
5970: 2e 20 20 54 68 65 20 70 65 72 63 65 6e 74 61 67  .  The percentag
5980: 65 20 61 74 20 74 68 65 20 72 69 67 68 74 20 73  e at the right s
5990: 68 6f 77 73 20 74 68 65 20 70 61 79 6c 6f 61 64  hows the payload
59a0: 0a 20 20 20 20 64 69 76 69 64 65 64 20 62 79 20  .    divided by 
59b0: 74 68 65 20 74 6f 74 61 6c 20 66 69 6c 65 20 73  the total file s
59c0: 69 7a 65 2e 0a 0a 50 65 72 63 65 6e 74 61 67 65  ize...Percentage
59d0: 20 6f 66 20 74 6f 74 61 6c 20 64 61 74 61 62 61   of total databa
59e0: 73 65 0a 0a 20 20 20 20 54 68 65 20 61 6d 6f 75  se..    The amou
59f0: 6e 74 20 6f 66 20 74 68 65 20 63 6f 6d 70 6c 65  nt of the comple
5a00: 74 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  te database file
5a10: 20 74 68 61 74 20 69 73 20 64 65 76 6f 74 65 64   that is devoted
5a20: 20 74 6f 20 73 74 6f 72 69 6e 67 0a 20 20 20 20   to storing.    
5a30: 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 64 65 73 63  information desc
5a40: 72 69 62 65 64 20 62 79 20 74 68 69 73 20 63 61  ribed by this ca
5a50: 74 65 67 6f 72 79 2e 0a 0a 4e 75 6d 62 65 72 20  tegory...Number 
5a60: 6f 66 20 65 6e 74 72 69 65 73 0a 0a 20 20 20 20  of entries..    
5a70: 54 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72  The total number
5a80: 20 6f 66 20 42 2d 54 72 65 65 20 6b 65 79 2f 76   of B-Tree key/v
5a90: 61 6c 75 65 20 70 61 69 72 73 20 73 74 6f 72 65  alue pairs store
5aa0: 64 20 75 6e 64 65 72 20 74 68 69 73 20 63 61 74  d under this cat
5ab0: 65 67 6f 72 79 2e 0a 0a 42 79 74 65 73 20 6f 66  egory...Bytes of
5ac0: 20 73 74 6f 72 61 67 65 20 63 6f 6e 73 75 6d 65   storage consume
5ad0: 64 0a 0a 20 20 20 20 54 68 65 20 74 6f 74 61 6c  d..    The total
5ae0: 20 61 6d 6f 75 6e 74 20 6f 66 20 64 69 73 6b 20   amount of disk 
5af0: 73 70 61 63 65 20 72 65 71 75 69 72 65 64 20 74  space required t
5b00: 6f 20 73 74 6f 72 65 20 61 6c 6c 20 42 2d 54 72  o store all B-Tr
5b10: 65 65 20 65 6e 74 72 69 65 73 0a 20 20 20 20 75  ee entries.    u
5b20: 6e 64 65 72 20 74 68 69 73 20 63 61 74 65 67 6f  nder this catego
5b30: 72 79 2e 20 20 54 68 65 20 69 73 20 74 68 65 20  ry.  The is the 
5b40: 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20  total number of 
5b50: 70 61 67 65 73 20 75 73 65 64 20 74 69 6d 65 73  pages used times
5b60: 0a 20 20 20 20 74 68 65 20 70 61 67 65 73 20 73  .    the pages s
5b70: 69 7a 65 2e 0a 0a 42 79 74 65 73 20 6f 66 20 70  ize...Bytes of p
5b80: 61 79 6c 6f 61 64 0a 0a 20 20 20 20 54 68 65 20  ayload..    The 
5b90: 61 6d 6f 75 6e 74 20 6f 66 20 70 61 79 6c 6f 61  amount of payloa
5ba0: 64 20 73 74 6f 72 65 64 20 75 6e 64 65 72 20 74  d stored under t
5bb0: 68 69 73 20 63 61 74 65 67 6f 72 79 2e 20 20 50  his category.  P
5bc0: 61 79 6c 6f 61 64 20 69 73 20 74 68 65 20 64 61  ayload is the da
5bd0: 74 61 0a 20 20 20 20 70 61 72 74 20 6f 66 20 74  ta.    part of t
5be0: 61 62 6c 65 20 65 6e 74 72 69 65 73 20 61 6e 64  able entries and
5bf0: 20 74 68 65 20 6b 65 79 20 70 61 72 74 20 6f 66   the key part of
5c00: 20 69 6e 64 65 78 20 65 6e 74 72 69 65 73 2e 20   index entries. 
5c10: 20 54 68 65 20 70 65 72 63 65 6e 74 61 67 65 0a   The percentage.
5c20: 20 20 20 20 61 74 20 74 68 65 20 72 69 67 68 74      at the right
5c30: 20 69 73 20 74 68 65 20 62 79 74 65 73 20 6f 66   is the bytes of
5c40: 20 70 61 79 6c 6f 61 64 20 64 69 76 69 64 65 64   payload divided
5c50: 20 62 79 20 74 68 65 20 62 79 74 65 73 20 6f 66   by the bytes of
5c60: 20 73 74 6f 72 61 67 65 20 0a 20 20 20 20 63 6f   storage .    co
5c70: 6e 73 75 6d 65 64 2e 0a 0a 41 76 65 72 61 67 65  nsumed...Average
5c80: 20 70 61 79 6c 6f 61 64 20 70 65 72 20 65 6e 74   payload per ent
5c90: 72 79 0a 0a 20 20 20 20 54 68 65 20 61 76 65 72  ry..    The aver
5ca0: 61 67 65 20 61 6d 6f 75 6e 74 20 6f 66 20 70 61  age amount of pa
5cb0: 79 6c 6f 61 64 20 6f 6e 20 65 61 63 68 20 65 6e  yload on each en
5cc0: 74 72 79 2e 20 20 54 68 69 73 20 69 73 20 6a 75  try.  This is ju
5cd0: 73 74 20 74 68 65 20 62 79 74 65 73 20 6f 66 0a  st the bytes of.
5ce0: 20 20 20 20 70 61 79 6c 6f 61 64 20 64 69 76 69      payload divi
5cf0: 64 65 64 20 62 79 20 74 68 65 20 6e 75 6d 62 65  ded by the numbe
5d00: 72 20 6f 66 20 65 6e 74 72 69 65 73 2e 0a 0a 41  r of entries...A
5d10: 76 65 72 61 67 65 20 75 6e 75 73 65 64 20 62 79  verage unused by
5d20: 74 65 73 20 70 65 72 20 65 6e 74 72 79 0a 0a 20  tes per entry.. 
5d30: 20 20 20 54 68 65 20 61 76 65 72 61 67 65 20 61     The average a
5d40: 6d 6f 75 6e 74 20 6f 66 20 66 72 65 65 20 73 70  mount of free sp
5d50: 61 63 65 20 72 65 6d 61 69 6e 69 6e 67 20 6f 6e  ace remaining on
5d60: 20 61 6c 6c 20 70 61 67 65 73 20 75 6e 64 65 72   all pages under
5d70: 20 74 68 69 73 0a 20 20 20 20 63 61 74 65 67 6f   this.    catego
5d80: 72 79 20 6f 6e 20 61 20 70 65 72 2d 65 6e 74 72  ry on a per-entr
5d90: 79 20 62 61 73 69 73 2e 20 20 54 68 69 73 20 69  y basis.  This i
5da0: 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  s the number of 
5db0: 75 6e 75 73 65 64 20 62 79 74 65 73 20 6f 6e 0a  unused bytes on.
5dc0: 20 20 20 20 61 6c 6c 20 70 61 67 65 73 20 64 69      all pages di
5dd0: 76 69 64 65 64 20 62 79 20 74 68 65 20 6e 75 6d  vided by the num
5de0: 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73 2e 0a  ber of entries..
5df0: 0a 4e 6f 6e 2d 73 65 71 75 65 6e 74 69 61 6c 20  .Non-sequential 
5e00: 70 61 67 65 73 0a 0a 20 20 20 20 54 68 65 20 6e  pages..    The n
5e10: 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 69  umber of pages i
5e20: 6e 20 74 68 65 20 74 61 62 6c 65 20 6f 72 20 69  n the table or i
5e30: 6e 64 65 78 20 74 68 61 74 20 61 72 65 20 6f 75  ndex that are ou
5e40: 74 20 6f 66 20 73 65 71 75 65 6e 63 65 2e 0a 20  t of sequence.. 
5e50: 20 20 20 4d 61 6e 79 20 66 69 6c 65 73 79 73 74     Many filesyst
5e60: 65 6d 73 20 61 72 65 20 6f 70 74 69 6d 69 7a 65  ems are optimize
5e70: 64 20 66 6f 72 20 73 65 71 75 65 6e 74 69 61 6c  d for sequential
5e80: 20 66 69 6c 65 20 61 63 63 65 73 73 20 73 6f 20   file access so 
5e90: 61 20 73 6d 61 6c 6c 0a 20 20 20 20 6e 75 6d 62  a small.    numb
5ea0: 65 72 20 6f 66 20 6e 6f 6e 2d 73 65 71 75 65 6e  er of non-sequen
5eb0: 74 69 61 6c 20 70 61 67 65 73 20 6d 69 67 68 74  tial pages might
5ec0: 20 72 65 73 75 6c 74 20 69 6e 20 66 61 73 74 65   result in faste
5ed0: 72 20 71 75 65 72 69 65 73 2c 0a 20 20 20 20 65  r queries,.    e
5ee0: 73 70 65 63 69 61 6c 6c 79 20 66 6f 72 20 6c 61  specially for la
5ef0: 72 67 65 72 20 64 61 74 61 62 61 73 65 20 66 69  rger database fi
5f00: 6c 65 73 20 74 68 61 74 20 64 6f 20 6e 6f 74 20  les that do not 
5f10: 66 69 74 20 69 6e 20 74 68 65 20 64 69 73 6b 20  fit in the disk 
5f20: 63 61 63 68 65 2e 0a 20 20 20 20 4e 6f 74 65 20  cache..    Note 
5f30: 74 68 61 74 20 61 66 74 65 72 20 72 75 6e 6e 69  that after runni
5f40: 6e 67 20 56 41 43 55 55 4d 2c 20 74 68 65 20 72  ng VACUUM, the r
5f50: 6f 6f 74 20 70 61 67 65 20 6f 66 20 65 61 63 68  oot page of each
5f60: 20 74 61 62 6c 65 20 6f 72 20 69 6e 64 65 78 20   table or index 
5f70: 69 73 0a 20 20 20 20 61 74 20 74 68 65 20 62 65  is.    at the be
5f80: 67 69 6e 6e 69 6e 67 20 6f 66 20 74 68 65 20 64  ginning of the d
5f90: 61 74 61 62 61 73 65 20 66 69 6c 65 20 61 6e 64  atabase file and
5fa0: 20 61 6c 6c 20 6f 74 68 65 72 20 70 61 67 65 73   all other pages
5fb0: 20 61 72 65 20 69 6e 20 61 0a 20 20 20 20 73 65   are in a.    se
5fc0: 70 61 72 61 74 65 20 70 61 72 74 20 6f 66 20 74  parate part of t
5fd0: 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  he database file
5fe0: 2c 20 72 65 73 75 6c 74 69 6e 67 20 69 6e 20 61  , resulting in a
5ff0: 20 73 69 6e 67 6c 65 20 6e 6f 6e 2d 0a 20 20 20   single non-.   
6000: 20 73 65 71 75 65 6e 74 69 61 6c 20 70 61 67 65   sequential page
6010: 2e 0a 0a 4d 61 78 69 6d 75 6d 20 70 61 79 6c 6f  ...Maximum paylo
6020: 61 64 20 70 65 72 20 65 6e 74 72 79 0a 0a 20 20  ad per entry..  
6030: 20 20 54 68 65 20 6c 61 72 67 65 73 74 20 70 61    The largest pa
6040: 79 6c 6f 61 64 20 73 69 7a 65 20 6f 66 20 61 6e  yload size of an
6050: 79 20 65 6e 74 72 79 2e 0a 0a 45 6e 74 72 69 65  y entry...Entrie
6060: 73 20 74 68 61 74 20 75 73 65 20 6f 76 65 72 66  s that use overf
6070: 6c 6f 77 0a 0a 20 20 20 20 54 68 65 20 6e 75 6d  low..    The num
6080: 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20 74  ber of entries t
6090: 68 61 74 20 75 73 65 72 20 6f 6e 65 20 6f 72 20  hat user one or 
60a0: 6d 6f 72 65 20 6f 76 65 72 66 6c 6f 77 20 70 61  more overflow pa
60b0: 67 65 73 2e 0a 0a 54 6f 74 61 6c 20 70 61 67 65  ges...Total page
60c0: 73 20 75 73 65 64 0a 0a 20 20 20 20 54 68 69 73  s used..    This
60d0: 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f   is the number o
60e0: 66 20 70 61 67 65 73 20 75 73 65 64 20 74 6f 20  f pages used to 
60f0: 68 6f 6c 64 20 61 6c 6c 20 69 6e 66 6f 72 6d 61  hold all informa
6100: 74 69 6f 6e 20 69 6e 20 74 68 65 20 63 75 72 72  tion in the curr
6110: 65 6e 74 0a 20 20 20 20 63 61 74 65 67 6f 72 79  ent.    category
6120: 2e 20 20 54 68 69 73 20 69 73 20 74 68 65 20 73  .  This is the s
6130: 75 6d 20 6f 66 20 69 6e 64 65 78 2c 20 70 72 69  um of index, pri
6140: 6d 61 72 79 2c 20 61 6e 64 20 6f 76 65 72 66 6c  mary, and overfl
6150: 6f 77 20 70 61 67 65 73 2e 0a 0a 49 6e 64 65 78  ow pages...Index
6160: 20 70 61 67 65 73 20 75 73 65 64 0a 0a 20 20 20   pages used..   
6170: 20 54 68 69 73 20 69 73 20 74 68 65 20 6e 75 6d   This is the num
6180: 62 65 72 20 6f 66 20 70 61 67 65 73 20 69 6e 20  ber of pages in 
6190: 61 20 74 61 62 6c 65 20 42 2d 74 72 65 65 20 74  a table B-tree t
61a0: 68 61 74 20 68 6f 6c 64 20 6f 6e 6c 79 20 6b 65  hat hold only ke
61b0: 79 20 28 72 6f 77 69 64 29 0a 20 20 20 20 69 6e  y (rowid).    in
61c0: 66 6f 72 6d 61 74 69 6f 6e 20 61 6e 64 20 6e 6f  formation and no
61d0: 20 64 61 74 61 2e 0a 0a 50 72 69 6d 61 72 79 20   data...Primary 
61e0: 70 61 67 65 73 20 75 73 65 64 0a 0a 20 20 20 20  pages used..    
61f0: 54 68 69 73 20 69 73 20 74 68 65 20 6e 75 6d 62  This is the numb
6200: 65 72 20 6f 66 20 42 2d 74 72 65 65 20 70 61 67  er of B-tree pag
6210: 65 73 20 74 68 61 74 20 68 6f 6c 64 20 62 6f 74  es that hold bot
6220: 68 20 6b 65 79 20 61 6e 64 20 64 61 74 61 2e 0a  h key and data..
6230: 0a 4f 76 65 72 66 6c 6f 77 20 70 61 67 65 73 20  .Overflow pages 
6240: 75 73 65 64 0a 0a 20 20 20 20 54 68 65 20 74 6f  used..    The to
6250: 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 6f 76  tal number of ov
6260: 65 72 66 6c 6f 77 20 70 61 67 65 73 20 75 73 65  erflow pages use
6270: 64 20 66 6f 72 20 74 68 69 73 20 63 61 74 65 67  d for this categ
6280: 6f 72 79 2e 0a 0a 55 6e 75 73 65 64 20 62 79 74  ory...Unused byt
6290: 65 73 20 6f 6e 20 69 6e 64 65 78 20 70 61 67 65  es on index page
62a0: 73 0a 0a 20 20 20 20 54 68 65 20 74 6f 74 61 6c  s..    The total
62b0: 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73   number of bytes
62c0: 20 6f 66 20 75 6e 75 73 65 64 20 73 70 61 63 65   of unused space
62d0: 20 6f 6e 20 61 6c 6c 20 69 6e 64 65 78 20 70 61   on all index pa
62e0: 67 65 73 2e 20 20 54 68 65 0a 20 20 20 20 70 65  ges.  The.    pe
62f0: 72 63 65 6e 74 61 67 65 20 61 74 20 74 68 65 20  rcentage at the 
6300: 72 69 67 68 74 20 69 73 20 74 68 65 20 6e 75 6d  right is the num
6310: 62 65 72 20 6f 66 20 75 6e 75 73 65 64 20 62 79  ber of unused by
6320: 74 65 73 20 64 69 76 69 64 65 64 20 62 79 20 74  tes divided by t
6330: 68 65 0a 20 20 20 20 74 6f 74 61 6c 20 6e 75 6d  he.    total num
6340: 62 65 72 20 6f 66 20 62 79 74 65 73 20 6f 6e 20  ber of bytes on 
6350: 69 6e 64 65 78 20 70 61 67 65 73 2e 0a 0a 55 6e  index pages...Un
6360: 75 73 65 64 20 62 79 74 65 73 20 6f 6e 20 70 72  used bytes on pr
6370: 69 6d 61 72 79 20 70 61 67 65 73 0a 0a 20 20 20  imary pages..   
6380: 20 54 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65   The total numbe
6390: 72 20 6f 66 20 62 79 74 65 73 20 6f 66 20 75 6e  r of bytes of un
63a0: 75 73 65 64 20 73 70 61 63 65 20 6f 6e 20 61 6c  used space on al
63b0: 6c 20 70 72 69 6d 61 72 79 20 70 61 67 65 73 2e  l primary pages.
63c0: 20 20 54 68 65 0a 20 20 20 20 70 65 72 63 65 6e    The.    percen
63d0: 74 61 67 65 20 61 74 20 74 68 65 20 72 69 67 68  tage at the righ
63e0: 74 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20  t is the number 
63f0: 6f 66 20 75 6e 75 73 65 64 20 62 79 74 65 73 20  of unused bytes 
6400: 64 69 76 69 64 65 64 20 62 79 20 74 68 65 0a 20  divided by the. 
6410: 20 20 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20     total number 
6420: 6f 66 20 62 79 74 65 73 20 6f 6e 20 70 72 69 6d  of bytes on prim
6430: 61 72 79 20 70 61 67 65 73 2e 0a 0a 55 6e 75 73  ary pages...Unus
6440: 65 64 20 62 79 74 65 73 20 6f 6e 20 6f 76 65 72  ed bytes on over
6450: 66 6c 6f 77 20 70 61 67 65 73 0a 0a 20 20 20 20  flow pages..    
6460: 54 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72  The total number
6470: 20 6f 66 20 62 79 74 65 73 20 6f 66 20 75 6e 75   of bytes of unu
6480: 73 65 64 20 73 70 61 63 65 20 6f 6e 20 61 6c 6c  sed space on all
6490: 20 6f 76 65 72 66 6c 6f 77 20 70 61 67 65 73 2e   overflow pages.
64a0: 20 20 54 68 65 0a 20 20 20 20 70 65 72 63 65 6e    The.    percen
64b0: 74 61 67 65 20 61 74 20 74 68 65 20 72 69 67 68  tage at the righ
64c0: 74 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20  t is the number 
64d0: 6f 66 20 75 6e 75 73 65 64 20 62 79 74 65 73 20  of unused bytes 
64e0: 64 69 76 69 64 65 64 20 62 79 20 74 68 65 0a 20  divided by the. 
64f0: 20 20 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20     total number 
6500: 6f 66 20 62 79 74 65 73 20 6f 6e 20 6f 76 65 72  of bytes on over
6510: 66 6c 6f 77 20 70 61 67 65 73 2e 0a 0a 55 6e 75  flow pages...Unu
6520: 73 65 64 20 62 79 74 65 73 20 6f 6e 20 61 6c 6c  sed bytes on all
6530: 20 70 61 67 65 73 0a 0a 20 20 20 20 54 68 65 20   pages..    The 
6540: 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20  total number of 
6550: 62 79 74 65 73 20 6f 66 20 75 6e 75 73 65 64 20  bytes of unused 
6560: 73 70 61 63 65 20 6f 6e 20 61 6c 6c 20 70 72 69  space on all pri
6570: 6d 61 72 79 20 61 6e 64 20 6f 76 65 72 66 6c 6f  mary and overflo
6580: 77 20 0a 20 20 20 20 70 61 67 65 73 2e 20 20 54  w .    pages.  T
6590: 68 65 20 70 65 72 63 65 6e 74 61 67 65 20 61 74  he percentage at
65a0: 20 74 68 65 20 72 69 67 68 74 20 69 73 20 74 68   the right is th
65b0: 65 20 6e 75 6d 62 65 72 20 6f 66 20 75 6e 75 73  e number of unus
65c0: 65 64 20 62 79 74 65 73 20 0a 20 20 20 20 64 69  ed bytes .    di
65d0: 76 69 64 65 64 20 62 79 20 74 68 65 20 74 6f 74  vided by the tot
65e0: 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74  al number of byt
65f0: 65 73 2e 0a 7d 0a 0a 23 20 4f 75 74 70 75 74 20  es..}..# Output 
6600: 61 20 64 75 6d 70 20 6f 66 20 74 68 65 20 69 6e  a dump of the in
6610: 2d 6d 65 6d 6f 72 79 20 64 61 74 61 62 61 73 65  -memory database
6620: 2e 20 54 68 69 73 20 63 61 6e 20 62 65 20 75 73  . This can be us
6630: 65 64 20 66 6f 72 20 6d 6f 72 65 0a 23 20 63 6f  ed for more.# co
6640: 6d 70 6c 65 78 20 6f 66 66 6c 69 6e 65 20 61 6e  mplex offline an
6650: 61 6c 79 73 69 73 2e 0a 23 0a 74 69 74 6c 65 6c  alysis..#.titlel
6660: 69 6e 65 20 7b 7d 0a 70 75 74 73 20 22 54 68 65  ine {}.puts "The
6670: 20 65 6e 74 69 72 65 20 74 65 78 74 20 6f 66 20   entire text of 
6680: 74 68 69 73 20 72 65 70 6f 72 74 20 63 61 6e 20  this report can 
6690: 62 65 20 73 6f 75 72 63 65 64 20 69 6e 74 6f 20  be sourced into 
66a0: 61 6e 79 20 53 51 4c 20 64 61 74 61 62 61 73 65  any SQL database
66b0: 22 0a 70 75 74 73 20 22 65 6e 67 69 6e 65 20 66  ".puts "engine f
66c0: 6f 72 20 66 75 72 74 68 65 72 20 61 6e 61 6c 79  or further analy
66d0: 73 69 73 2e 20 20 41 6c 6c 20 6f 66 20 74 68 65  sis.  All of the
66e0: 20 74 65 78 74 20 61 62 6f 76 65 20 69 73 20 61   text above is a
66f0: 6e 20 53 51 4c 20 63 6f 6d 6d 65 6e 74 2e 22 0a  n SQL comment.".
6700: 70 75 74 73 20 22 54 68 65 20 64 61 74 61 20 75  puts "The data u
6710: 73 65 64 20 74 6f 20 67 65 6e 65 72 61 74 65 20  sed to generate 
6720: 74 68 69 73 20 72 65 70 6f 72 74 20 66 6f 6c 6c  this report foll
6730: 6f 77 73 3a 22 0a 70 75 74 73 20 22 2a 2f 22 0a  ows:".puts "*/".
6740: 70 75 74 73 20 22 42 45 47 49 4e 3b 22 0a 70 75  puts "BEGIN;".pu
6750: 74 73 20 24 74 61 62 6c 65 64 65 66 0a 75 6e 73  ts $tabledef.uns
6760: 65 74 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 78  et -nocomplain x
6770: 0a 6d 65 6d 20 65 76 61 6c 20 7b 53 45 4c 45 43  .mem eval {SELEC
6780: 54 20 2a 20 46 52 4f 4d 20 73 70 61 63 65 5f 75  T * FROM space_u
6790: 73 65 64 7d 20 78 20 7b 0a 20 20 70 75 74 73 20  sed} x {.  puts 
67a0: 2d 6e 6f 6e 65 77 6c 69 6e 65 20 22 49 4e 53 45  -nonewline "INSE
67b0: 52 54 20 49 4e 54 4f 20 73 70 61 63 65 5f 75 73  RT INTO space_us
67c0: 65 64 20 56 41 4c 55 45 53 22 0a 20 20 73 65 74  ed VALUES".  set
67d0: 20 73 65 70 20 28 0a 20 20 66 6f 72 65 61 63 68   sep (.  foreach
67e0: 20 63 6f 6c 20 24 78 28 2a 29 20 7b 0a 20 20 20   col $x(*) {.   
67f0: 20 73 65 74 20 76 20 24 78 28 24 63 6f 6c 29 0a   set v $x($col).
6800: 20 20 20 20 69 66 20 7b 24 76 3d 3d 22 22 20 7c      if {$v=="" |
6810: 7c 20 21 5b 73 74 72 69 6e 67 20 69 73 20 64 6f  | ![string is do
6820: 75 62 6c 65 20 24 76 5d 7d 20 7b 73 65 74 20 76  uble $v]} {set v
6830: 20 5b 71 75 6f 74 65 20 24 76 5d 7d 0a 20 20 20   [quote $v]}.   
6840: 20 70 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65   puts -nonewline
6850: 20 24 73 65 70 24 76 0a 20 20 20 20 73 65 74 20   $sep$v.    set 
6860: 73 65 70 20 2c 0a 20 20 7d 0a 20 20 70 75 74 73  sep ,.  }.  puts
6870: 20 22 29 3b 22 0a 7d 0a 70 75 74 73 20 22 43 4f   ");".}.puts "CO
6880: 4d 4d 49 54 3b 22 0a 0a 7d 20 65 72 72 5d 7d 20  MMIT;"..} err]} 
6890: 7b 0a 20 20 70 75 74 73 20 22 45 52 52 4f 52 3a  {.  puts "ERROR:
68a0: 20 24 65 72 72 22 0a 20 20 70 75 74 73 20 24 65   $err".  puts $e
68b0: 72 72 6f 72 49 6e 66 6f 0a 20 20 65 78 69 74 20  rrorInfo.  exit 
68c0: 31 0a 7d 0a                                      1.}.