/ Hex Artifact Content
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Artifact ab7d9bf68062907282a64b3e12ccbfad47193c5a:


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 0a 23 20 41 72 67 75 6d  catch {..# Argum
00d0: 65 6e 74 20 24 74 6e 61 6d 65 20 69 73 20 74 68  ent $tname is th
00e0: 65 20 6e 61 6d 65 20 6f 66 20 61 20 74 61 62 6c  e name of a tabl
00f0: 65 20 77 69 74 68 69 6e 20 74 68 65 20 64 61 74  e within the dat
0100: 61 62 61 73 65 20 6f 70 65 6e 65 64 20 62 79 0a  abase opened by.
0110: 23 20 64 61 74 61 62 61 73 65 20 68 61 6e 64 6c  # database handl
0120: 65 20 5b 64 62 5d 2e 20 52 65 74 75 72 6e 20 74  e [db]. Return t
0130: 72 75 65 20 69 66 20 69 74 20 69 73 20 61 20 57  rue if it is a W
0140: 49 54 48 4f 55 54 20 52 4f 57 49 44 20 74 61 62  ITHOUT ROWID tab
0150: 6c 65 2c 20 6f 72 0a 23 20 66 61 6c 73 65 20 6f  le, or.# false o
0160: 74 68 65 72 77 69 73 65 2e 0a 23 0a 70 72 6f 63  therwise..#.proc
0170: 20 69 73 5f 77 69 74 68 6f 75 74 5f 72 6f 77 69   is_without_rowi
0180: 64 20 7b 74 6e 61 6d 65 7d 20 7b 0a 20 20 73 65  d {tname} {.  se
0190: 74 20 74 20 5b 73 74 72 69 6e 67 20 6d 61 70 20  t t [string map 
01a0: 7b 27 20 27 27 7d 20 24 74 6e 61 6d 65 5d 0a 20  {' ''} $tname]. 
01b0: 20 64 62 20 65 76 61 6c 20 22 50 52 41 47 4d 41   db eval "PRAGMA
01c0: 20 69 6e 64 65 78 5f 6c 69 73 74 20 3d 20 27 24   index_list = '$
01d0: 74 27 22 20 6f 20 7b 0a 20 20 20 20 69 66 20 7b  t'" o {.    if {
01e0: 24 6f 28 6f 72 69 67 69 6e 29 20 3d 3d 20 22 70  $o(origin) == "p
01f0: 6b 22 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20  k"} {.      set 
0200: 6e 20 24 6f 28 6e 61 6d 65 29 0a 20 20 20 20 20  n $o(name).     
0210: 20 69 66 20 7b 30 3d 3d 5b 64 62 20 6f 6e 65 20   if {0==[db one 
0220: 7b 20 53 45 4c 45 43 54 20 63 6f 75 6e 74 28 2a  { SELECT count(*
0230: 29 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61  ) FROM sqlite_ma
0240: 73 74 65 72 20 57 48 45 52 45 20 6e 61 6d 65 3d  ster WHERE name=
0250: 24 6e 20 7d 5d 7d 20 7b 0a 20 20 20 20 20 20 20  $n }]} {.       
0260: 20 72 65 74 75 72 6e 20 31 0a 20 20 20 20 20 20   return 1.      
0270: 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65  }.    }.  }.  re
0280: 74 75 72 6e 20 30 0a 7d 0a 0a 23 20 52 65 61 64  turn 0.}..# Read
0290: 20 61 6e 64 20 72 75 6e 20 54 43 4c 20 63 6f 6d   and run TCL com
02a0: 6d 61 6e 64 73 20 66 72 6f 6d 20 73 74 61 6e 64  mands from stand
02b0: 61 72 64 20 69 6e 70 75 74 2e 20 20 55 73 65 64  ard input.  Used
02c0: 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74 0a 23 20   to implement.# 
02d0: 74 68 65 20 2d 2d 74 63 6c 73 68 20 6f 70 74 69  the --tclsh opti
02e0: 6f 6e 2e 0a 23 0a 70 72 6f 63 20 74 63 6c 73 68  on..#.proc tclsh
02f0: 20 7b 7d 20 7b 0a 20 20 73 65 74 20 6c 69 6e 65   {} {.  set line
0300: 20 7b 7d 0a 20 20 77 68 69 6c 65 20 7b 21 5b 65   {}.  while {![e
0310: 6f 66 20 73 74 64 69 6e 5d 7d 20 7b 0a 20 20 20  of stdin]} {.   
0320: 20 69 66 20 7b 24 6c 69 6e 65 21 3d 22 22 7d 20   if {$line!=""} 
0330: 7b 0a 20 20 20 20 20 20 70 75 74 73 20 2d 6e 6f  {.      puts -no
0340: 6e 65 77 6c 69 6e 65 20 22 3e 20 22 0a 20 20 20  newline "> ".   
0350: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20   } else {.      
0360: 70 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20  puts -nonewline 
0370: 22 25 20 22 0a 20 20 20 20 7d 0a 20 20 20 20 66  "% ".    }.    f
0380: 6c 75 73 68 20 73 74 64 6f 75 74 0a 20 20 20 20  lush stdout.    
0390: 61 70 70 65 6e 64 20 6c 69 6e 65 20 5b 67 65 74  append line [get
03a0: 73 20 73 74 64 69 6e 5d 0a 20 20 20 20 69 66 20  s stdin].    if 
03b0: 7b 5b 69 6e 66 6f 20 63 6f 6d 70 6c 65 74 65 20  {[info complete 
03c0: 24 6c 69 6e 65 5d 7d 20 7b 0a 20 20 20 20 20 20  $line]} {.      
03d0: 69 66 20 7b 5b 63 61 74 63 68 20 7b 75 70 6c 65  if {[catch {uple
03e0: 76 65 6c 20 23 30 20 24 6c 69 6e 65 7d 20 72 65  vel #0 $line} re
03f0: 73 75 6c 74 5d 7d 20 7b 0a 20 20 20 20 20 20 20  sult]} {.       
0400: 20 70 75 74 73 20 73 74 64 65 72 72 20 22 45 72   puts stderr "Er
0410: 72 6f 72 3a 20 24 72 65 73 75 6c 74 22 0a 20 20  ror: $result".  
0420: 20 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 24 72      } elseif {$r
0430: 65 73 75 6c 74 21 3d 22 22 7d 20 7b 0a 20 20 20  esult!=""} {.   
0440: 20 20 20 20 20 70 75 74 73 20 24 72 65 73 75 6c       puts $resul
0450: 74 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  t.      }.      
0460: 73 65 74 20 6c 69 6e 65 20 7b 7d 0a 20 20 20 20  set line {}.    
0470: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 61  } else {.      a
0480: 70 70 65 6e 64 20 6c 69 6e 65 20 5c 6e 0a 20 20  ppend line \n.  
0490: 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 0a 23 20 47 65    }.  }.}...# Ge
04a0: 74 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 74 68  t the name of th
04b0: 65 20 64 61 74 61 62 61 73 65 20 74 6f 20 61 6e  e database to an
04c0: 61 6c 79 7a 65 0a 23 0a 70 72 6f 63 20 75 73 61  alyze.#.proc usa
04d0: 67 65 20 7b 7d 20 7b 0a 20 20 73 65 74 20 61 72  ge {} {.  set ar
04e0: 67 76 30 20 5b 66 69 6c 65 20 72 6f 6f 74 6e 61  gv0 [file rootna
04f0: 6d 65 20 5b 66 69 6c 65 20 74 61 69 6c 20 5b 69  me [file tail [i
0500: 6e 66 6f 20 6e 61 6d 65 6f 66 65 78 65 63 75 74  nfo nameofexecut
0510: 61 62 6c 65 5d 5d 5d 0a 20 20 70 75 74 73 20 73  able]]].  puts s
0520: 74 64 65 72 72 20 22 55 73 61 67 65 3a 20 24 61  tderr "Usage: $a
0530: 72 67 76 30 20 3f 2d 2d 70 61 67 65 69 6e 66 6f  rgv0 ?--pageinfo
0540: 3f 20 3f 2d 2d 73 74 61 74 73 3f 20 64 61 74 61  ? ?--stats? data
0550: 62 61 73 65 2d 66 69 6c 65 6e 61 6d 65 22 0a 20  base-filename". 
0560: 20 70 75 74 73 20 73 74 64 65 72 72 20 7b 0a 41   puts stderr {.A
0570: 6e 61 6c 79 7a 65 20 74 68 65 20 53 51 4c 69 74  nalyze the SQLit
0580: 65 33 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  e3 database file
0590: 20 73 70 65 63 69 66 69 65 64 20 62 79 20 74 68   specified by th
05a0: 65 20 22 64 61 74 61 62 61 73 65 2d 66 69 6c 65  e "database-file
05b0: 6e 61 6d 65 22 0a 61 72 67 75 6d 65 6e 74 20 61  name".argument a
05c0: 6e 64 20 6f 75 74 70 75 74 20 61 20 72 65 70 6f  nd output a repo
05d0: 72 74 20 64 65 74 61 69 6c 69 6e 67 20 73 69 7a  rt detailing siz
05e0: 65 20 61 6e 64 20 73 74 6f 72 61 67 65 20 65 66  e and storage ef
05f0: 66 69 63 69 65 6e 63 79 0a 69 6e 66 6f 72 6d 61  ficiency.informa
0600: 74 69 6f 6e 20 66 6f 72 20 74 68 65 20 64 61 74  tion for the dat
0610: 61 62 61 73 65 20 61 6e 64 20 69 74 73 20 63 6f  abase and its co
0620: 6e 73 74 69 74 75 65 6e 74 20 74 61 62 6c 65 73  nstituent tables
0630: 20 61 6e 64 20 69 6e 64 65 78 65 73 2e 0a 0a 4f   and indexes...O
0640: 70 74 69 6f 6e 73 3a 0a 0a 20 20 20 2d 2d 70 61  ptions:..   --pa
0650: 67 65 69 6e 66 6f 20 20 20 53 68 6f 77 20 68 6f  geinfo   Show ho
0660: 77 20 65 61 63 68 20 70 61 67 65 20 6f 66 20 74  w each page of t
0670: 68 65 20 64 61 74 61 62 61 73 65 2d 66 69 6c 65  he database-file
0680: 20 69 73 20 75 73 65 64 0a 0a 20 20 20 2d 2d 73   is used..   --s
0690: 74 61 74 73 20 20 20 20 20 20 4f 75 74 70 75 74  tats      Output
06a0: 20 53 51 4c 20 74 65 78 74 20 74 68 61 74 20 63   SQL text that c
06b0: 72 65 61 74 65 73 20 61 20 6e 65 77 20 64 61 74  reates a new dat
06c0: 61 62 61 73 65 20 63 6f 6e 74 61 69 6e 69 6e 67  abase containing
06d0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
06e0: 20 73 74 61 74 69 73 74 69 63 73 20 61 62 6f 75   statistics abou
06f0: 74 20 74 68 65 20 64 61 74 61 62 61 73 65 20 74  t the database t
0700: 68 61 74 20 77 61 73 20 61 6e 61 6c 79 7a 65 64  hat was analyzed
0710: 0a 0a 20 20 20 2d 2d 74 63 6c 73 68 20 20 20 20  ..   --tclsh    
0720: 20 20 52 75 6e 20 74 68 65 20 62 75 69 6c 74 2d    Run the built-
0730: 69 6e 20 54 43 4c 20 69 6e 74 65 72 70 72 65 74  in TCL interpret
0740: 65 72 20 69 6e 74 65 72 61 63 74 69 76 65 6c 79  er interactively
0750: 20 28 66 6f 72 20 64 65 62 75 67 67 69 6e 67 29   (for debugging)
0760: 0a 0a 20 20 20 2d 2d 76 65 72 73 69 6f 6e 20 20  ..   --version  
0770: 20 20 53 68 6f 77 20 74 68 65 20 76 65 72 73 69    Show the versi
0780: 6f 6e 20 6e 75 6d 62 65 72 20 6f 66 20 53 51 4c  on number of SQL
0790: 69 74 65 0a 7d 0a 20 20 65 78 69 74 20 31 0a 7d  ite.}.  exit 1.}
07a0: 0a 73 65 74 20 66 69 6c 65 5f 74 6f 5f 61 6e 61  .set file_to_ana
07b0: 6c 79 7a 65 20 7b 7d 0a 73 65 74 20 66 6c 61 67  lyze {}.set flag
07c0: 73 28 2d 70 61 67 65 69 6e 66 6f 29 20 30 0a 73  s(-pageinfo) 0.s
07d0: 65 74 20 66 6c 61 67 73 28 2d 73 74 61 74 73 29  et flags(-stats)
07e0: 20 30 0a 73 65 74 20 66 6c 61 67 73 28 2d 64 65   0.set flags(-de
07f0: 62 75 67 29 20 30 0a 61 70 70 65 6e 64 20 61 72  bug) 0.append ar
0800: 67 76 20 7b 7d 0a 66 6f 72 65 61 63 68 20 61 72  gv {}.foreach ar
0810: 67 20 24 61 72 67 76 20 7b 0a 20 20 69 66 20 7b  g $argv {.  if {
0820: 5b 72 65 67 65 78 70 20 7b 5e 2d 2b 70 61 67 65  [regexp {^-+page
0830: 69 6e 66 6f 24 7d 20 24 61 72 67 5d 7d 20 7b 0a  info$} $arg]} {.
0840: 20 20 20 20 73 65 74 20 66 6c 61 67 73 28 2d 70      set flags(-p
0850: 61 67 65 69 6e 66 6f 29 20 31 0a 20 20 7d 20 65  ageinfo) 1.  } e
0860: 6c 73 65 69 66 20 7b 5b 72 65 67 65 78 70 20 7b  lseif {[regexp {
0870: 5e 2d 2b 73 74 61 74 73 24 7d 20 24 61 72 67 5d  ^-+stats$} $arg]
0880: 7d 20 7b 0a 20 20 20 20 73 65 74 20 66 6c 61 67  } {.    set flag
0890: 73 28 2d 73 74 61 74 73 29 20 31 0a 20 20 7d 20  s(-stats) 1.  } 
08a0: 65 6c 73 65 69 66 20 7b 5b 72 65 67 65 78 70 20  elseif {[regexp 
08b0: 7b 5e 2d 2b 64 65 62 75 67 24 7d 20 24 61 72 67  {^-+debug$} $arg
08c0: 5d 7d 20 7b 0a 20 20 20 20 73 65 74 20 66 6c 61  ]} {.    set fla
08d0: 67 73 28 2d 64 65 62 75 67 29 20 31 0a 20 20 7d  gs(-debug) 1.  }
08e0: 20 65 6c 73 65 69 66 20 7b 5b 72 65 67 65 78 70   elseif {[regexp
08f0: 20 7b 5e 2d 2b 74 63 6c 73 68 24 7d 20 24 61 72   {^-+tclsh$} $ar
0900: 67 5d 7d 20 7b 0a 20 20 20 20 74 63 6c 73 68 0a  g]} {.    tclsh.
0910: 20 20 20 20 65 78 69 74 20 30 0a 20 20 7d 20 65      exit 0.  } e
0920: 6c 73 65 69 66 20 7b 5b 72 65 67 65 78 70 20 7b  lseif {[regexp {
0930: 5e 2d 2b 76 65 72 73 69 6f 6e 24 7d 20 24 61 72  ^-+version$} $ar
0940: 67 5d 7d 20 7b 0a 20 20 20 20 73 71 6c 69 74 65  g]} {.    sqlite
0950: 33 20 6d 65 6d 20 3a 6d 65 6d 6f 72 79 3a 0a 20  3 mem :memory:. 
0960: 20 20 20 70 75 74 73 20 5b 6d 65 6d 20 6f 6e 65     puts [mem one
0970: 20 7b 53 45 4c 45 43 54 20 73 71 6c 69 74 65 5f   {SELECT sqlite_
0980: 76 65 72 73 69 6f 6e 28 29 7c 7c 27 20 27 7c 7c  version()||' '||
0990: 73 71 6c 69 74 65 5f 73 6f 75 72 63 65 5f 69 64  sqlite_source_id
09a0: 28 29 7d 5d 0a 20 20 20 20 6d 65 6d 20 63 6c 6f  ()}].    mem clo
09b0: 73 65 0a 20 20 20 20 65 78 69 74 20 30 0a 20 20  se.    exit 0.  
09c0: 7d 20 65 6c 73 65 69 66 20 7b 5b 72 65 67 65 78  } elseif {[regex
09d0: 70 20 7b 5e 2d 7d 20 24 61 72 67 5d 7d 20 7b 0a  p {^-} $arg]} {.
09e0: 20 20 20 20 70 75 74 73 20 73 74 64 65 72 72 20      puts stderr 
09f0: 22 55 6e 6b 6e 6f 77 6e 20 6f 70 74 69 6f 6e 3a  "Unknown option:
0a00: 20 24 61 72 67 22 0a 20 20 20 20 75 73 61 67 65   $arg".    usage
0a10: 0a 20 20 7d 20 65 6c 73 65 69 66 20 7b 24 66 69  .  } elseif {$fi
0a20: 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 21 3d 22  le_to_analyze!="
0a30: 22 7d 20 7b 0a 20 20 20 20 75 73 61 67 65 0a 20  "} {.    usage. 
0a40: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65   } else {.    se
0a50: 74 20 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a  t file_to_analyz
0a60: 65 20 24 61 72 67 0a 20 20 7d 0a 7d 0a 69 66 20  e $arg.  }.}.if 
0a70: 7b 24 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a  {$file_to_analyz
0a80: 65 3d 3d 22 22 7d 20 75 73 61 67 65 0a 73 65 74  e==""} usage.set
0a90: 20 72 6f 6f 74 5f 66 69 6c 65 6e 61 6d 65 20 24   root_filename $
0aa0: 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 0a  file_to_analyze.
0ab0: 72 65 67 65 78 70 20 7b 5e 66 69 6c 65 3a 28 2f  regexp {^file:(/
0ac0: 2f 29 3f 28 5b 5e 3f 5d 2a 29 7d 20 24 66 69 6c  /)?([^?]*)} $fil
0ad0: 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 20 61 6c 6c  e_to_analyze all
0ae0: 20 78 31 20 72 6f 6f 74 5f 66 69 6c 65 6e 61 6d   x1 root_filenam
0af0: 65 0a 69 66 20 7b 21 5b 66 69 6c 65 20 65 78 69  e.if {![file exi
0b00: 73 74 73 20 24 72 6f 6f 74 5f 66 69 6c 65 6e 61  sts $root_filena
0b10: 6d 65 5d 7d 20 7b 0a 20 20 70 75 74 73 20 73 74  me]} {.  puts st
0b20: 64 65 72 72 20 22 4e 6f 20 73 75 63 68 20 66 69  derr "No such fi
0b30: 6c 65 3a 20 24 72 6f 6f 74 5f 66 69 6c 65 6e 61  le: $root_filena
0b40: 6d 65 22 0a 20 20 65 78 69 74 20 31 0a 7d 0a 69  me".  exit 1.}.i
0b50: 66 20 7b 21 5b 66 69 6c 65 20 72 65 61 64 61 62  f {![file readab
0b60: 6c 65 20 24 72 6f 6f 74 5f 66 69 6c 65 6e 61 6d  le $root_filenam
0b70: 65 5d 7d 20 7b 0a 20 20 70 75 74 73 20 73 74 64  e]} {.  puts std
0b80: 65 72 72 20 22 46 69 6c 65 20 69 73 20 6e 6f 74  err "File is not
0b90: 20 72 65 61 64 61 62 6c 65 3a 20 24 72 6f 6f 74   readable: $root
0ba0: 5f 66 69 6c 65 6e 61 6d 65 22 0a 20 20 65 78 69  _filename".  exi
0bb0: 74 20 31 0a 7d 0a 73 65 74 20 74 72 75 65 5f 66  t 1.}.set true_f
0bc0: 69 6c 65 5f 73 69 7a 65 20 5b 66 69 6c 65 20 73  ile_size [file s
0bd0: 69 7a 65 20 24 72 6f 6f 74 5f 66 69 6c 65 6e 61  ize $root_filena
0be0: 6d 65 5d 0a 69 66 20 7b 24 74 72 75 65 5f 66 69  me].if {$true_fi
0bf0: 6c 65 5f 73 69 7a 65 3c 35 31 32 7d 20 7b 0a 20  le_size<512} {. 
0c00: 20 70 75 74 73 20 73 74 64 65 72 72 20 22 45 6d   puts stderr "Em
0c10: 70 74 79 20 6f 72 20 6d 61 6c 66 6f 72 6d 65 64  pty or malformed
0c20: 20 64 61 74 61 62 61 73 65 3a 20 24 72 6f 6f 74   database: $root
0c30: 5f 66 69 6c 65 6e 61 6d 65 22 0a 20 20 65 78 69  _filename".  exi
0c40: 74 20 31 0a 7d 0a 0a 23 20 43 6f 6d 70 75 74 65  t 1.}..# Compute
0c50: 20 74 68 65 20 74 6f 74 61 6c 20 66 69 6c 65 20   the total file 
0c60: 73 69 7a 65 20 61 73 73 75 6d 69 6e 67 20 74 65  size assuming te
0c70: 73 74 5f 6d 75 6c 74 69 70 6c 65 78 6f 72 20 69  st_multiplexor i
0c80: 73 20 62 65 69 6e 67 20 75 73 65 64 2e 0a 23 20  s being used..# 
0c90: 41 73 73 75 6d 65 20 74 68 61 74 20 53 51 4c 49  Assume that SQLI
0ca0: 54 45 5f 45 4e 41 42 4c 45 5f 38 5f 33 5f 4e 41  TE_ENABLE_8_3_NA
0cb0: 4d 45 53 20 6d 69 67 68 74 20 62 65 20 65 6e 61  MES might be ena
0cc0: 62 6c 65 64 0a 23 0a 73 65 74 20 65 78 74 65 6e  bled.#.set exten
0cd0: 73 69 6f 6e 20 5b 66 69 6c 65 20 65 78 74 65 6e  sion [file exten
0ce0: 73 69 6f 6e 20 24 72 6f 6f 74 5f 66 69 6c 65 6e  sion $root_filen
0cf0: 61 6d 65 5d 0a 73 65 74 20 70 61 74 74 65 72 6e  ame].set pattern
0d00: 20 24 72 6f 6f 74 5f 66 69 6c 65 6e 61 6d 65 0a   $root_filename.
0d10: 61 70 70 65 6e 64 20 70 61 74 74 65 72 6e 20 7b  append pattern {
0d20: 5b 30 2d 33 5d 5b 30 2d 39 5d 5b 30 2d 39 5d 7d  [0-3][0-9][0-9]}
0d30: 0a 66 6f 72 65 61 63 68 20 66 20 5b 67 6c 6f 62  .foreach f [glob
0d40: 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 24 70 61   -nocomplain $pa
0d50: 74 74 65 72 6e 5d 20 7b 0a 20 20 69 6e 63 72 20  ttern] {.  incr 
0d60: 74 72 75 65 5f 66 69 6c 65 5f 73 69 7a 65 20 5b  true_file_size [
0d70: 66 69 6c 65 20 73 69 7a 65 20 24 66 5d 0a 20 20  file size $f].  
0d80: 73 65 74 20 65 78 74 65 6e 73 69 6f 6e 20 7b 7d  set extension {}
0d90: 0a 7d 0a 69 66 20 7b 5b 73 74 72 69 6e 67 20 6c  .}.if {[string l
0da0: 65 6e 67 74 68 20 24 65 78 74 65 6e 73 69 6f 6e  ength $extension
0db0: 5d 3e 3d 32 20 26 26 20 5b 73 74 72 69 6e 67 20  ]>=2 && [string 
0dc0: 6c 65 6e 67 74 68 20 24 65 78 74 65 6e 73 69 6f  length $extensio
0dd0: 6e 5d 3c 3d 34 7d 20 7b 0a 20 20 73 65 74 20 70  n]<=4} {.  set p
0de0: 61 74 74 65 72 6e 20 5b 66 69 6c 65 20 72 6f 6f  attern [file roo
0df0: 74 6e 61 6d 65 20 24 72 6f 6f 74 5f 66 69 6c 65  tname $root_file
0e00: 6e 61 6d 65 5d 0a 20 20 61 70 70 65 6e 64 20 70  name].  append p
0e10: 61 74 74 65 72 6e 20 7b 2e 5b 30 2d 33 5d 5b 30  attern {.[0-3][0
0e20: 2d 39 5d 5b 30 2d 39 5d 7d 0a 20 20 66 6f 72 65  -9][0-9]}.  fore
0e30: 61 63 68 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63  ach f [glob -noc
0e40: 6f 6d 70 6c 61 69 6e 20 24 70 61 74 74 65 72 6e  omplain $pattern
0e50: 5d 20 7b 0a 20 20 20 20 69 6e 63 72 20 74 72 75  ] {.    incr tru
0e60: 65 5f 66 69 6c 65 5f 73 69 7a 65 20 5b 66 69 6c  e_file_size [fil
0e70: 65 20 73 69 7a 65 20 24 66 5d 0a 20 20 7d 0a 7d  e size $f].  }.}
0e80: 0a 0a 23 20 4f 70 65 6e 20 74 68 65 20 64 61 74  ..# Open the dat
0e90: 61 62 61 73 65 0a 23 0a 69 66 20 7b 5b 63 61 74  abase.#.if {[cat
0ea0: 63 68 20 7b 73 71 6c 69 74 65 33 20 64 62 20 24  ch {sqlite3 db $
0eb0: 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 20  file_to_analyze 
0ec0: 2d 75 72 69 20 31 7d 20 6d 73 67 5d 7d 20 7b 0a  -uri 1} msg]} {.
0ed0: 20 20 70 75 74 73 20 73 74 64 65 72 72 20 22 65    puts stderr "e
0ee0: 72 72 6f 72 20 74 72 79 69 6e 67 20 74 6f 20 6f  rror trying to o
0ef0: 70 65 6e 20 24 66 69 6c 65 5f 74 6f 5f 61 6e 61  pen $file_to_ana
0f00: 6c 79 7a 65 3a 20 24 6d 73 67 22 0a 20 20 65 78  lyze: $msg".  ex
0f10: 69 74 20 31 0a 7d 0a 69 66 20 7b 24 66 6c 61 67  it 1.}.if {$flag
0f20: 73 28 2d 64 65 62 75 67 29 7d 20 7b 0a 20 20 70  s(-debug)} {.  p
0f30: 72 6f 63 20 64 62 74 72 61 63 65 20 7b 74 78 74  roc dbtrace {txt
0f40: 7d 20 7b 70 75 74 73 20 24 74 78 74 3b 20 66 6c  } {puts $txt; fl
0f50: 75 73 68 20 73 74 64 6f 75 74 3b 7d 0a 20 20 64  ush stdout;}.  d
0f60: 62 20 74 72 61 63 65 20 3a 3a 64 62 74 72 61 63  b trace ::dbtrac
0f70: 65 0a 7d 0a 0a 64 62 20 65 76 61 6c 20 7b 53 45  e.}..db eval {SE
0f80: 4c 45 43 54 20 63 6f 75 6e 74 28 2a 29 20 46 52  LECT count(*) FR
0f90: 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72  OM sqlite_master
0fa0: 7d 0a 73 65 74 20 70 61 67 65 53 69 7a 65 20 5b  }.set pageSize [
0fb0: 65 78 70 72 20 7b 77 69 64 65 28 5b 64 62 20 6f  expr {wide([db o
0fc0: 6e 65 20 7b 50 52 41 47 4d 41 20 70 61 67 65 5f  ne {PRAGMA page_
0fd0: 73 69 7a 65 7d 5d 29 7d 5d 0a 0a 69 66 20 7b 24  size}])}]..if {$
0fe0: 66 6c 61 67 73 28 2d 70 61 67 65 69 6e 66 6f 29  flags(-pageinfo)
0ff0: 7d 20 7b 0a 20 20 64 62 20 65 76 61 6c 20 7b 43  } {.  db eval {C
1000: 52 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41  REATE VIRTUAL TA
1010: 42 4c 45 20 74 65 6d 70 2e 73 74 61 74 20 55 53  BLE temp.stat US
1020: 49 4e 47 20 64 62 73 74 61 74 7d 0a 20 20 64 62  ING dbstat}.  db
1030: 20 65 76 61 6c 20 7b 53 45 4c 45 43 54 20 6e 61   eval {SELECT na
1040: 6d 65 2c 20 70 61 74 68 2c 20 70 61 67 65 6e 6f  me, path, pageno
1050: 20 46 52 4f 4d 20 74 65 6d 70 2e 73 74 61 74 20   FROM temp.stat 
1060: 4f 52 44 45 52 20 42 59 20 70 61 67 65 6e 6f 7d  ORDER BY pageno}
1070: 20 7b 0a 20 20 20 20 70 75 74 73 20 22 24 70 61   {.    puts "$pa
1080: 67 65 6e 6f 20 24 6e 61 6d 65 20 24 70 61 74 68  geno $name $path
1090: 22 0a 20 20 7d 0a 20 20 65 78 69 74 20 30 0a 7d  ".  }.  exit 0.}
10a0: 0a 69 66 20 7b 24 66 6c 61 67 73 28 2d 73 74 61  .if {$flags(-sta
10b0: 74 73 29 7d 20 7b 0a 20 20 64 62 20 65 76 61 6c  ts)} {.  db eval
10c0: 20 7b 43 52 45 41 54 45 20 56 49 52 54 55 41 4c   {CREATE VIRTUAL
10d0: 20 54 41 42 4c 45 20 74 65 6d 70 2e 73 74 61 74   TABLE temp.stat
10e0: 20 55 53 49 4e 47 20 64 62 73 74 61 74 7d 0a 20   USING dbstat}. 
10f0: 20 70 75 74 73 20 22 42 45 47 49 4e 3b 22 0a 20   puts "BEGIN;". 
1100: 20 70 75 74 73 20 22 43 52 45 41 54 45 20 54 41   puts "CREATE TA
1110: 42 4c 45 20 73 74 61 74 73 28 22 0a 20 20 70 75  BLE stats(".  pu
1120: 74 73 20 22 20 20 6e 61 6d 65 20 20 20 20 20 20  ts "  name      
1130: 20 53 54 52 49 4e 47 2c 20 20 20 20 20 20 20 20   STRING,        
1140: 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 61     /* Name of ta
1150: 62 6c 65 20 6f 72 20 69 6e 64 65 78 20 2a 2f 22  ble or index */"
1160: 0a 20 20 70 75 74 73 20 22 20 20 70 61 74 68 20  .  puts "  path 
1170: 20 20 20 20 20 20 49 4e 54 45 47 45 52 2c 20 20        INTEGER,  
1180: 20 20 20 20 20 20 20 20 2f 2a 20 50 61 74 68 20          /* Path 
1190: 74 6f 20 70 61 67 65 20 66 72 6f 6d 20 72 6f 6f  to page from roo
11a0: 74 20 2a 2f 22 0a 20 20 70 75 74 73 20 22 20 20  t */".  puts "  
11b0: 70 61 67 65 6e 6f 20 20 20 20 20 49 4e 54 45 47  pageno     INTEG
11c0: 45 52 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ER,          /* 
11d0: 50 61 67 65 20 6e 75 6d 62 65 72 20 2a 2f 22 0a  Page number */".
11e0: 20 20 70 75 74 73 20 22 20 20 70 61 67 65 74 79    puts "  pagety
11f0: 70 65 20 20 20 53 54 52 49 4e 47 2c 20 20 20 20  pe   STRING,    
1200: 20 20 20 20 20 20 20 2f 2a 20 27 69 6e 74 65 72         /* 'inter
1210: 6e 61 6c 27 2c 20 27 6c 65 61 66 27 20 6f 72 20  nal', 'leaf' or 
1220: 27 6f 76 65 72 66 6c 6f 77 27 20 2a 2f 22 0a 20  'overflow' */". 
1230: 20 70 75 74 73 20 22 20 20 6e 63 65 6c 6c 20 20   puts "  ncell  
1240: 20 20 20 20 49 4e 54 45 47 45 52 2c 20 20 20 20      INTEGER,    
1250: 20 20 20 20 20 20 2f 2a 20 43 65 6c 6c 73 20 6f        /* Cells o
1260: 6e 20 70 61 67 65 20 28 30 20 66 6f 72 20 6f 76  n page (0 for ov
1270: 65 72 66 6c 6f 77 29 20 2a 2f 22 0a 20 20 70 75  erflow) */".  pu
1280: 74 73 20 22 20 20 70 61 79 6c 6f 61 64 20 20 20  ts "  payload   
1290: 20 49 4e 54 45 47 45 52 2c 20 20 20 20 20 20 20   INTEGER,       
12a0: 20 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 70     /* Bytes of p
12b0: 61 79 6c 6f 61 64 20 6f 6e 20 74 68 69 73 20 70  ayload on this p
12c0: 61 67 65 20 2a 2f 22 0a 20 20 70 75 74 73 20 22  age */".  puts "
12d0: 20 20 75 6e 75 73 65 64 20 20 20 20 20 49 4e 54    unused     INT
12e0: 45 47 45 52 2c 20 20 20 20 20 20 20 20 20 20 2f  EGER,          /
12f0: 2a 20 42 79 74 65 73 20 6f 66 20 75 6e 75 73 65  * Bytes of unuse
1300: 64 20 73 70 61 63 65 20 6f 6e 20 74 68 69 73 20  d space on this 
1310: 70 61 67 65 20 2a 2f 22 0a 20 20 70 75 74 73 20  page */".  puts 
1320: 22 20 20 6d 78 5f 70 61 79 6c 6f 61 64 20 49 4e  "  mx_payload IN
1330: 54 45 47 45 52 2c 20 20 20 20 20 20 20 20 20 20  TEGER,          
1340: 2f 2a 20 4c 61 72 67 65 73 74 20 70 61 79 6c 6f  /* Largest paylo
1350: 61 64 20 73 69 7a 65 20 6f 66 20 61 6c 6c 20 63  ad size of all c
1360: 65 6c 6c 73 20 2a 2f 22 0a 20 20 70 75 74 73 20  ells */".  puts 
1370: 22 20 20 70 67 6f 66 66 73 65 74 20 20 20 49 4e  "  pgoffset   IN
1380: 54 45 47 45 52 2c 20 20 20 20 20 20 20 20 20 20  TEGER,          
1390: 2f 2a 20 4f 66 66 73 65 74 20 6f 66 20 70 61 67  /* Offset of pag
13a0: 65 20 69 6e 20 66 69 6c 65 20 2a 2f 22 0a 20 20  e in file */".  
13b0: 70 75 74 73 20 22 20 20 70 67 73 69 7a 65 20 20  puts "  pgsize  
13c0: 20 20 20 49 4e 54 45 47 45 52 20 20 20 20 20 20     INTEGER      
13d0: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
13e0: 74 68 65 20 70 61 67 65 20 2a 2f 22 0a 20 20 70  the page */".  p
13f0: 75 74 73 20 22 29 3b 22 0a 20 20 64 62 20 65 76  uts ");".  db ev
1400: 61 6c 20 7b 53 45 4c 45 43 54 20 71 75 6f 74 65  al {SELECT quote
1410: 28 6e 61 6d 65 29 20 7c 7c 20 27 2c 27 20 7c 7c  (name) || ',' ||
1420: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1430: 20 20 20 71 75 6f 74 65 28 70 61 74 68 29 20 7c     quote(path) |
1440: 7c 20 27 2c 27 20 7c 7c 0a 20 20 20 20 20 20 20  | ',' ||.       
1450: 20 20 20 20 20 20 20 20 20 20 20 71 75 6f 74 65             quote
1460: 28 70 61 67 65 6e 6f 29 20 7c 7c 20 27 2c 27 20  (pageno) || ',' 
1470: 7c 7c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ||.             
1480: 20 20 20 20 20 71 75 6f 74 65 28 70 61 67 65 74       quote(paget
1490: 79 70 65 29 20 7c 7c 20 27 2c 27 20 7c 7c 0a 20  ype) || ',' ||. 
14a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14b0: 20 71 75 6f 74 65 28 6e 63 65 6c 6c 29 20 7c 7c   quote(ncell) ||
14c0: 20 27 2c 27 20 7c 7c 0a 20 20 20 20 20 20 20 20   ',' ||.        
14d0: 20 20 20 20 20 20 20 20 20 20 71 75 6f 74 65 28            quote(
14e0: 70 61 79 6c 6f 61 64 29 20 7c 7c 20 27 2c 27 20  payload) || ',' 
14f0: 7c 7c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ||.             
1500: 20 20 20 20 20 71 75 6f 74 65 28 75 6e 75 73 65       quote(unuse
1510: 64 29 20 7c 7c 20 27 2c 27 20 7c 7c 0a 20 20 20  d) || ',' ||.   
1520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 71                 q
1530: 75 6f 74 65 28 6d 78 5f 70 61 79 6c 6f 61 64 29  uote(mx_payload)
1540: 20 7c 7c 20 27 2c 27 20 7c 7c 0a 20 20 20 20 20   || ',' ||.     
1550: 20 20 20 20 20 20 20 20 20 20 20 20 20 71 75 6f               quo
1560: 74 65 28 70 67 6f 66 66 73 65 74 29 20 7c 7c 20  te(pgoffset) || 
1570: 27 2c 27 20 7c 7c 0a 20 20 20 20 20 20 20 20 20  ',' ||.         
1580: 20 20 20 20 20 20 20 20 20 71 75 6f 74 65 28 70           quote(p
1590: 67 73 69 7a 65 29 20 41 53 20 78 20 46 52 4f 4d  gsize) AS x FROM
15a0: 20 73 74 61 74 7d 20 7b 0a 20 20 20 20 70 75 74   stat} {.    put
15b0: 73 20 22 49 4e 53 45 52 54 20 49 4e 54 4f 20 73  s "INSERT INTO s
15c0: 74 61 74 73 20 56 41 4c 55 45 53 28 24 78 29 3b  tats VALUES($x);
15d0: 22 0a 20 20 7d 0a 20 20 70 75 74 73 20 22 43 4f  ".  }.  puts "CO
15e0: 4d 4d 49 54 3b 22 0a 20 20 65 78 69 74 20 30 0a  MMIT;".  exit 0.
15f0: 7d 0a 0a 0a 23 20 49 6e 2d 6d 65 6d 6f 72 79 20  }...# In-memory 
1600: 64 61 74 61 62 61 73 65 20 66 6f 72 20 63 6f 6c  database for col
1610: 6c 65 63 74 69 6e 67 20 73 74 61 74 69 73 74 69  lecting statisti
1620: 63 73 2e 20 54 68 69 73 20 73 63 72 69 70 74 20  cs. This script 
1630: 6c 6f 6f 70 73 20 74 68 72 6f 75 67 68 0a 23 20  loops through.# 
1640: 74 68 65 20 74 61 62 6c 65 73 20 61 6e 64 20 69  the tables and i
1650: 6e 64 69 63 65 73 20 69 6e 20 74 68 65 20 64 61  ndices in the da
1660: 74 61 62 61 73 65 20 62 65 69 6e 67 20 61 6e 61  tabase being ana
1670: 6c 79 7a 65 64 2c 20 61 64 64 69 6e 67 20 61 20  lyzed, adding a 
1680: 72 6f 77 20 66 6f 72 20 65 61 63 68 0a 23 20 74  row for each.# t
1690: 6f 20 61 6e 20 69 6e 2d 6d 65 6d 6f 72 79 20 64  o an in-memory d
16a0: 61 74 61 62 61 73 65 20 28 66 6f 72 20 77 68 69  atabase (for whi
16b0: 63 68 20 74 68 65 20 73 63 68 65 6d 61 20 69 73  ch the schema is
16c0: 20 73 68 6f 77 6e 20 62 65 6c 6f 77 29 2e 20 49   shown below). I
16d0: 74 20 74 68 65 6e 0a 23 20 71 75 65 72 69 65 73  t then.# queries
16e0: 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 64   the in-memory d
16f0: 62 20 74 6f 20 70 72 6f 64 75 63 65 20 74 68 65  b to produce the
1700: 20 73 70 61 63 65 2d 61 6e 61 6c 79 73 69 73 20   space-analysis 
1710: 72 65 70 6f 72 74 2e 0a 23 0a 73 71 6c 69 74 65  report..#.sqlite
1720: 33 20 6d 65 6d 20 3a 6d 65 6d 6f 72 79 3a 0a 69  3 mem :memory:.i
1730: 66 20 7b 24 66 6c 61 67 73 28 2d 64 65 62 75 67  f {$flags(-debug
1740: 29 7d 20 7b 0a 20 20 70 72 6f 63 20 64 62 74 72  )} {.  proc dbtr
1750: 61 63 65 20 7b 74 78 74 7d 20 7b 70 75 74 73 20  ace {txt} {puts 
1760: 24 74 78 74 3b 20 66 6c 75 73 68 20 73 74 64 6f  $txt; flush stdo
1770: 75 74 3b 7d 0a 20 20 6d 65 6d 20 74 72 61 63 65  ut;}.  mem trace
1780: 20 3a 3a 64 62 74 72 61 63 65 0a 7d 0a 73 65 74   ::dbtrace.}.set
1790: 20 74 61 62 6c 65 64 65 66 20 7b 43 52 45 41 54   tabledef {CREAT
17a0: 45 20 54 41 42 4c 45 20 73 70 61 63 65 5f 75 73  E TABLE space_us
17b0: 65 64 28 0a 20 20 20 6e 61 6d 65 20 63 6c 6f 62  ed(.   name clob
17c0: 2c 20 20 20 20 20 20 20 20 2d 2d 20 4e 61 6d 65  ,        -- Name
17d0: 20 6f 66 20 61 20 74 61 62 6c 65 20 6f 72 20 69   of a table or i
17e0: 6e 64 65 78 20 69 6e 20 74 68 65 20 64 61 74 61  ndex in the data
17f0: 62 61 73 65 20 66 69 6c 65 0a 20 20 20 74 62 6c  base file.   tbl
1800: 6e 61 6d 65 20 63 6c 6f 62 2c 20 20 20 20 20 2d  name clob,     -
1810: 2d 20 4e 61 6d 65 20 6f 66 20 61 73 73 6f 63 69  - Name of associ
1820: 61 74 65 64 20 74 61 62 6c 65 0a 20 20 20 69 73  ated table.   is
1830: 5f 69 6e 64 65 78 20 62 6f 6f 6c 65 61 6e 2c 20  _index boolean, 
1840: 2d 2d 20 54 52 55 45 20 69 66 20 69 74 20 69 73  -- TRUE if it is
1850: 20 61 6e 20 69 6e 64 65 78 2c 20 66 61 6c 73 65   an index, false
1860: 20 66 6f 72 20 61 20 74 61 62 6c 65 0a 20 20 20   for a table.   
1870: 69 73 5f 77 69 74 68 6f 75 74 5f 72 6f 77 69 64  is_without_rowid
1880: 20 62 6f 6f 6c 65 61 6e 2c 20 2d 2d 20 54 52 55   boolean, -- TRU
1890: 45 20 69 66 20 57 49 54 48 4f 55 54 20 52 4f 57  E if WITHOUT ROW
18a0: 49 44 20 74 61 62 6c 65 20 20 0a 20 20 20 6e 65  ID table  .   ne
18b0: 6e 74 72 79 20 69 6e 74 2c 20 20 20 20 20 20 20  ntry int,       
18c0: 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20 65 6e 74  -- Number of ent
18d0: 72 69 65 73 20 69 6e 20 74 68 65 20 42 54 72 65  ries in the BTre
18e0: 65 0a 20 20 20 6c 65 61 66 5f 65 6e 74 72 69 65  e.   leaf_entrie
18f0: 73 20 69 6e 74 2c 20 2d 2d 20 4e 75 6d 62 65 72  s int, -- Number
1900: 20 6f 66 20 6c 65 61 66 20 65 6e 74 72 69 65 73   of leaf entries
1910: 0a 20 20 20 64 65 70 74 68 20 69 6e 74 2c 20 20  .   depth int,  
1920: 20 20 20 20 20 20 2d 2d 20 44 65 70 74 68 20 6f        -- Depth o
1930: 66 20 74 68 65 20 62 2d 74 72 65 65 0a 20 20 20  f the b-tree.   
1940: 70 61 79 6c 6f 61 64 20 69 6e 74 2c 20 20 20 20  payload int,    
1950: 20 20 2d 2d 20 54 6f 74 61 6c 20 61 6d 6f 75 6e    -- Total amoun
1960: 74 20 6f 66 20 64 61 74 61 20 73 74 6f 72 65 64  t of data stored
1970: 20 69 6e 20 74 68 69 73 20 74 61 62 6c 65 20 6f   in this table o
1980: 72 20 69 6e 64 65 78 0a 20 20 20 6f 76 66 6c 5f  r index.   ovfl_
1990: 70 61 79 6c 6f 61 64 20 69 6e 74 2c 20 2d 2d 20  payload int, -- 
19a0: 54 6f 74 61 6c 20 61 6d 6f 75 6e 74 20 6f 66 20  Total amount of 
19b0: 64 61 74 61 20 73 74 6f 72 65 64 20 6f 6e 20 6f  data stored on o
19c0: 76 65 72 66 6c 6f 77 20 70 61 67 65 73 0a 20 20  verflow pages.  
19d0: 20 6f 76 66 6c 5f 63 6e 74 20 69 6e 74 2c 20 20   ovfl_cnt int,  
19e0: 20 20 20 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20     -- Number of 
19f0: 65 6e 74 72 69 65 73 20 74 68 61 74 20 75 73 65  entries that use
1a00: 20 6f 76 65 72 66 6c 6f 77 0a 20 20 20 6d 78 5f   overflow.   mx_
1a10: 70 61 79 6c 6f 61 64 20 69 6e 74 2c 20 20 20 2d  payload int,   -
1a20: 2d 20 4d 61 78 69 6d 75 6d 20 70 61 79 6c 6f 61  - Maximum payloa
1a30: 64 20 73 69 7a 65 0a 20 20 20 69 6e 74 5f 70 61  d size.   int_pa
1a40: 67 65 73 20 69 6e 74 2c 20 20 20 20 2d 2d 20 4e  ges int,    -- N
1a50: 75 6d 62 65 72 20 6f 66 20 69 6e 74 65 72 69 6f  umber of interio
1a60: 72 20 70 61 67 65 73 20 75 73 65 64 0a 20 20 20  r pages used.   
1a70: 6c 65 61 66 5f 70 61 67 65 73 20 69 6e 74 2c 20  leaf_pages int, 
1a80: 20 20 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20 6c    -- Number of l
1a90: 65 61 66 20 70 61 67 65 73 20 75 73 65 64 0a 20  eaf pages used. 
1aa0: 20 20 6f 76 66 6c 5f 70 61 67 65 73 20 69 6e 74    ovfl_pages int
1ab0: 2c 20 20 20 2d 2d 20 4e 75 6d 62 65 72 20 6f 66  ,   -- Number of
1ac0: 20 6f 76 65 72 66 6c 6f 77 20 70 61 67 65 73 20   overflow pages 
1ad0: 75 73 65 64 0a 20 20 20 69 6e 74 5f 75 6e 75 73  used.   int_unus
1ae0: 65 64 20 69 6e 74 2c 20 20 20 2d 2d 20 4e 75 6d  ed int,   -- Num
1af0: 62 65 72 20 6f 66 20 75 6e 75 73 65 64 20 62 79  ber of unused by
1b00: 74 65 73 20 6f 6e 20 69 6e 74 65 72 69 6f 72 20  tes on interior 
1b10: 70 61 67 65 73 0a 20 20 20 6c 65 61 66 5f 75 6e  pages.   leaf_un
1b20: 75 73 65 64 20 69 6e 74 2c 20 20 2d 2d 20 4e 75  used int,  -- Nu
1b30: 6d 62 65 72 20 6f 66 20 75 6e 75 73 65 64 20 62  mber of unused b
1b40: 79 74 65 73 20 6f 6e 20 70 72 69 6d 61 72 79 20  ytes on primary 
1b50: 70 61 67 65 73 0a 20 20 20 6f 76 66 6c 5f 75 6e  pages.   ovfl_un
1b60: 75 73 65 64 20 69 6e 74 2c 20 20 2d 2d 20 4e 75  used int,  -- Nu
1b70: 6d 62 65 72 20 6f 66 20 75 6e 75 73 65 64 20 62  mber of unused b
1b80: 79 74 65 73 20 6f 6e 20 6f 76 65 72 66 6c 6f 77  ytes on overflow
1b90: 20 70 61 67 65 73 0a 20 20 20 67 61 70 5f 63 6e   pages.   gap_cn
1ba0: 74 20 69 6e 74 2c 20 20 20 20 20 20 2d 2d 20 4e  t int,      -- N
1bb0: 75 6d 62 65 72 20 6f 66 20 67 61 70 73 20 69 6e  umber of gaps in
1bc0: 20 74 68 65 20 70 61 67 65 20 6c 61 79 6f 75 74   the page layout
1bd0: 0a 20 20 20 63 6f 6d 70 72 65 73 73 65 64 5f 73  .   compressed_s
1be0: 69 7a 65 20 69 6e 74 20 20 2d 2d 20 54 6f 74 61  ize int  -- Tota
1bf0: 6c 20 62 79 74 65 73 20 73 74 6f 72 65 64 20 6f  l bytes stored o
1c00: 6e 20 64 69 73 6b 0a 29 3b 7d 0a 6d 65 6d 20 65  n disk.);}.mem e
1c10: 76 61 6c 20 24 74 61 62 6c 65 64 65 66 0a 0a 23  val $tabledef..#
1c20: 20 43 72 65 61 74 65 20 61 20 74 65 6d 70 6f 72   Create a tempor
1c30: 61 72 79 20 22 64 62 73 74 61 74 22 20 76 69 72  ary "dbstat" vir
1c40: 74 75 61 6c 20 74 61 62 6c 65 2e 0a 23 0a 64 62  tual table..#.db
1c50: 20 65 76 61 6c 20 7b 43 52 45 41 54 45 20 56 49   eval {CREATE VI
1c60: 52 54 55 41 4c 20 54 41 42 4c 45 20 74 65 6d 70  RTUAL TABLE temp
1c70: 2e 73 74 61 74 20 55 53 49 4e 47 20 64 62 73 74  .stat USING dbst
1c80: 61 74 7d 0a 64 62 20 65 76 61 6c 20 7b 43 52 45  at}.db eval {CRE
1c90: 41 54 45 20 54 45 4d 50 20 54 41 42 4c 45 20 64  ATE TEMP TABLE d
1ca0: 62 73 74 61 74 20 41 53 20 53 45 4c 45 43 54 20  bstat AS SELECT 
1cb0: 2a 20 46 52 4f 4d 20 74 65 6d 70 2e 73 74 61 74  * FROM temp.stat
1cc0: 0a 20 20 20 20 20 20 20 20 20 4f 52 44 45 52 20  .         ORDER 
1cd0: 42 59 20 6e 61 6d 65 2c 20 70 61 74 68 7d 0a 64  BY name, path}.d
1ce0: 62 20 65 76 61 6c 20 7b 44 52 4f 50 20 54 41 42  b eval {DROP TAB
1cf0: 4c 45 20 74 65 6d 70 2e 73 74 61 74 7d 0a 0a 73  LE temp.stat}..s
1d00: 65 74 20 69 73 43 6f 6d 70 72 65 73 73 65 64 20  et isCompressed 
1d10: 30 0a 73 65 74 20 63 6f 6d 70 72 65 73 73 4f 76  0.set compressOv
1d20: 65 72 68 65 61 64 20 30 0a 73 65 74 20 64 65 70  erhead 0.set dep
1d30: 74 68 20 30 0a 73 65 74 20 73 71 6c 20 7b 20 53  th 0.set sql { S
1d40: 45 4c 45 43 54 20 6e 61 6d 65 2c 20 74 62 6c 5f  ELECT name, tbl_
1d50: 6e 61 6d 65 20 46 52 4f 4d 20 73 71 6c 69 74 65  name FROM sqlite
1d60: 5f 6d 61 73 74 65 72 20 57 48 45 52 45 20 72 6f  _master WHERE ro
1d70: 6f 74 70 61 67 65 3e 30 20 7d 0a 66 6f 72 65 61  otpage>0 }.forea
1d80: 63 68 20 7b 6e 61 6d 65 20 74 62 6c 6e 61 6d 65  ch {name tblname
1d90: 7d 20 5b 63 6f 6e 63 61 74 20 73 71 6c 69 74 65  } [concat sqlite
1da0: 5f 6d 61 73 74 65 72 20 73 71 6c 69 74 65 5f 6d  _master sqlite_m
1db0: 61 73 74 65 72 20 5b 64 62 20 65 76 61 6c 20 24  aster [db eval $
1dc0: 73 71 6c 5d 5d 20 7b 0a 0a 20 20 73 65 74 20 69  sql]] {..  set i
1dd0: 73 5f 69 6e 64 65 78 20 5b 65 78 70 72 20 7b 24  s_index [expr {$
1de0: 6e 61 6d 65 21 3d 24 74 62 6c 6e 61 6d 65 7d 5d  name!=$tblname}]
1df0: 0a 20 20 73 65 74 20 69 73 5f 77 69 74 68 6f 75  .  set is_withou
1e00: 74 5f 72 6f 77 69 64 20 5b 69 73 5f 77 69 74 68  t_rowid [is_with
1e10: 6f 75 74 5f 72 6f 77 69 64 20 24 6e 61 6d 65 5d  out_rowid $name]
1e20: 0a 20 20 64 62 20 65 76 61 6c 20 7b 0a 20 20 20  .  db eval {.   
1e30: 20 53 45 4c 45 43 54 20 0a 20 20 20 20 20 20 73   SELECT .      s
1e40: 75 6d 28 6e 63 65 6c 6c 29 20 41 53 20 6e 65 6e  um(ncell) AS nen
1e50: 74 72 79 2c 0a 20 20 20 20 20 20 73 75 6d 28 28  try,.      sum((
1e60: 70 61 67 65 74 79 70 65 3d 3d 27 6c 65 61 66 27  pagetype=='leaf'
1e70: 29 2a 6e 63 65 6c 6c 29 20 41 53 20 6c 65 61 66  )*ncell) AS leaf
1e80: 5f 65 6e 74 72 69 65 73 2c 0a 20 20 20 20 20 20  _entries,.      
1e90: 73 75 6d 28 70 61 79 6c 6f 61 64 29 20 41 53 20  sum(payload) AS 
1ea0: 70 61 79 6c 6f 61 64 2c 0a 20 20 20 20 20 20 73  payload,.      s
1eb0: 75 6d 28 28 70 61 67 65 74 79 70 65 3d 3d 27 6f  um((pagetype=='o
1ec0: 76 65 72 66 6c 6f 77 27 29 20 2a 20 70 61 79 6c  verflow') * payl
1ed0: 6f 61 64 29 20 41 53 20 6f 76 66 6c 5f 70 61 79  oad) AS ovfl_pay
1ee0: 6c 6f 61 64 2c 0a 20 20 20 20 20 20 73 75 6d 28  load,.      sum(
1ef0: 70 61 74 68 20 4c 49 4b 45 20 27 25 2b 30 30 30  path LIKE '%+000
1f00: 30 30 30 27 29 20 41 53 20 6f 76 66 6c 5f 63 6e  000') AS ovfl_cn
1f10: 74 2c 0a 20 20 20 20 20 20 6d 61 78 28 6d 78 5f  t,.      max(mx_
1f20: 70 61 79 6c 6f 61 64 29 20 41 53 20 6d 78 5f 70  payload) AS mx_p
1f30: 61 79 6c 6f 61 64 2c 0a 20 20 20 20 20 20 73 75  ayload,.      su
1f40: 6d 28 70 61 67 65 74 79 70 65 3d 3d 27 69 6e 74  m(pagetype=='int
1f50: 65 72 6e 61 6c 27 29 20 41 53 20 69 6e 74 5f 70  ernal') AS int_p
1f60: 61 67 65 73 2c 0a 20 20 20 20 20 20 73 75 6d 28  ages,.      sum(
1f70: 70 61 67 65 74 79 70 65 3d 3d 27 6c 65 61 66 27  pagetype=='leaf'
1f80: 29 20 41 53 20 6c 65 61 66 5f 70 61 67 65 73 2c  ) AS leaf_pages,
1f90: 0a 20 20 20 20 20 20 73 75 6d 28 70 61 67 65 74  .      sum(paget
1fa0: 79 70 65 3d 3d 27 6f 76 65 72 66 6c 6f 77 27 29  ype=='overflow')
1fb0: 20 41 53 20 6f 76 66 6c 5f 70 61 67 65 73 2c 0a   AS ovfl_pages,.
1fc0: 20 20 20 20 20 20 73 75 6d 28 28 70 61 67 65 74        sum((paget
1fd0: 79 70 65 3d 3d 27 69 6e 74 65 72 6e 61 6c 27 29  ype=='internal')
1fe0: 20 2a 20 75 6e 75 73 65 64 29 20 41 53 20 69 6e   * unused) AS in
1ff0: 74 5f 75 6e 75 73 65 64 2c 0a 20 20 20 20 20 20  t_unused,.      
2000: 73 75 6d 28 28 70 61 67 65 74 79 70 65 3d 3d 27  sum((pagetype=='
2010: 6c 65 61 66 27 29 20 2a 20 75 6e 75 73 65 64 29  leaf') * unused)
2020: 20 41 53 20 6c 65 61 66 5f 75 6e 75 73 65 64 2c   AS leaf_unused,
2030: 0a 20 20 20 20 20 20 73 75 6d 28 28 70 61 67 65  .      sum((page
2040: 74 79 70 65 3d 3d 27 6f 76 65 72 66 6c 6f 77 27  type=='overflow'
2050: 29 20 2a 20 75 6e 75 73 65 64 29 20 41 53 20 6f  ) * unused) AS o
2060: 76 66 6c 5f 75 6e 75 73 65 64 2c 0a 20 20 20 20  vfl_unused,.    
2070: 20 20 73 75 6d 28 70 67 73 69 7a 65 29 20 41 53    sum(pgsize) AS
2080: 20 63 6f 6d 70 72 65 73 73 65 64 5f 73 69 7a 65   compressed_size
2090: 2c 0a 20 20 20 20 20 20 6d 61 78 28 28 6c 65 6e  ,.      max((len
20a0: 67 74 68 28 43 41 53 45 20 57 48 45 4e 20 70 61  gth(CASE WHEN pa
20b0: 74 68 20 4c 49 4b 45 20 27 25 2b 25 27 20 54 48  th LIKE '%+%' TH
20c0: 45 4e 20 27 27 20 45 4c 53 45 20 70 61 74 68 20  EN '' ELSE path 
20d0: 45 4e 44 29 2b 33 29 2f 34 29 0a 20 20 20 20 20  END)+3)/4).     
20e0: 20 20 20 41 53 20 64 65 70 74 68 0a 20 20 20 20     AS depth.    
20f0: 46 52 4f 4d 20 74 65 6d 70 2e 64 62 73 74 61 74  FROM temp.dbstat
2100: 20 57 48 45 52 45 20 6e 61 6d 65 20 3d 20 24 6e   WHERE name = $n
2110: 61 6d 65 0a 20 20 7d 20 62 72 65 61 6b 0a 0a 20  ame.  } break.. 
2120: 20 73 65 74 20 74 6f 74 61 6c 5f 70 61 67 65 73   set total_pages
2130: 20 5b 65 78 70 72 20 7b 24 6c 65 61 66 5f 70 61   [expr {$leaf_pa
2140: 67 65 73 2b 24 69 6e 74 5f 70 61 67 65 73 2b 24  ges+$int_pages+$
2150: 6f 76 66 6c 5f 70 61 67 65 73 7d 5d 0a 20 20 73  ovfl_pages}].  s
2160: 65 74 20 73 74 6f 72 61 67 65 20 5b 65 78 70 72  et storage [expr
2170: 20 7b 24 74 6f 74 61 6c 5f 70 61 67 65 73 2a 24   {$total_pages*$
2180: 70 61 67 65 53 69 7a 65 7d 5d 0a 20 20 69 66 20  pageSize}].  if 
2190: 7b 21 24 69 73 43 6f 6d 70 72 65 73 73 65 64 20  {!$isCompressed 
21a0: 26 26 20 24 73 74 6f 72 61 67 65 3e 24 63 6f 6d  && $storage>$com
21b0: 70 72 65 73 73 65 64 5f 73 69 7a 65 7d 20 7b 0a  pressed_size} {.
21c0: 20 20 20 20 73 65 74 20 69 73 43 6f 6d 70 72 65      set isCompre
21d0: 73 73 65 64 20 31 0a 20 20 20 20 73 65 74 20 63  ssed 1.    set c
21e0: 6f 6d 70 72 65 73 73 4f 76 65 72 68 65 61 64 20  ompressOverhead 
21f0: 31 34 0a 20 20 7d 0a 0a 20 20 23 20 43 6f 6c 75  14.  }..  # Colu
2200: 6d 6e 20 27 67 61 70 5f 63 6e 74 27 20 69 73 20  mn 'gap_cnt' is 
2210: 73 65 74 20 74 6f 20 74 68 65 20 6e 75 6d 62 65  set to the numbe
2220: 72 20 6f 66 20 6e 6f 6e 2d 63 6f 6e 74 69 67 75  r of non-contigu
2230: 6f 75 73 20 65 6e 74 72 69 65 73 20 69 6e 20 74  ous entries in t
2240: 68 65 0a 20 20 23 20 6c 69 73 74 20 6f 66 20 70  he.  # list of p
2250: 61 67 65 73 20 76 69 73 69 74 65 64 20 69 66 20  ages visited if 
2260: 74 68 65 20 62 2d 74 72 65 65 20 73 74 72 75 63  the b-tree struc
2270: 74 75 72 65 20 69 73 20 74 72 61 76 65 72 73 65  ture is traverse
2280: 64 20 69 6e 20 61 20 74 6f 70 2d 64 6f 77 6e 0a  d in a top-down.
2290: 20 20 23 20 66 61 73 68 69 6f 6e 20 28 65 61 63    # fashion (eac
22a0: 68 20 6e 6f 64 65 20 76 69 73 69 74 65 64 20 62  h node visited b
22b0: 65 66 6f 72 65 20 69 74 73 20 63 68 69 6c 64 2d  efore its child-
22c0: 74 72 65 65 20 69 73 20 70 61 73 73 65 64 29 2e  tree is passed).
22d0: 20 41 6e 79 20 6f 76 65 72 66 6c 6f 77 0a 20 20   Any overflow.  
22e0: 23 20 63 68 61 69 6e 73 20 70 72 65 73 65 6e 74  # chains present
22f0: 20 61 72 65 20 74 72 61 76 65 72 73 65 64 20 66   are traversed f
2300: 72 6f 6d 20 73 74 61 72 74 20 74 6f 20 66 69 6e  rom start to fin
2310: 69 73 68 20 62 65 66 6f 72 65 20 61 6e 79 20 63  ish before any c
2320: 68 69 6c 64 2d 74 72 65 65 0a 20 20 23 20 69 73  hild-tree.  # is
2330: 2e 0a 20 20 23 0a 20 20 73 65 74 20 67 61 70 5f  ..  #.  set gap_
2340: 63 6e 74 20 30 0a 20 20 73 65 74 20 70 72 65 76  cnt 0.  set prev
2350: 20 30 0a 20 20 64 62 20 65 76 61 6c 20 7b 0a 20   0.  db eval {. 
2360: 20 20 20 53 45 4c 45 43 54 20 70 61 67 65 6e 6f     SELECT pageno
2370: 2c 20 70 61 67 65 74 79 70 65 20 46 52 4f 4d 20  , pagetype FROM 
2380: 74 65 6d 70 2e 64 62 73 74 61 74 0a 20 20 20 20  temp.dbstat.    
2390: 20 57 48 45 52 45 20 6e 61 6d 65 3d 24 6e 61 6d   WHERE name=$nam
23a0: 65 0a 20 20 20 20 20 4f 52 44 45 52 20 42 59 20  e.     ORDER BY 
23b0: 70 61 67 65 6e 6f 0a 20 20 7d 20 7b 0a 20 20 20  pageno.  } {.   
23c0: 20 69 66 20 7b 24 70 72 65 76 3e 30 20 26 26 20   if {$prev>0 && 
23d0: 24 70 61 67 65 74 79 70 65 3d 3d 22 6c 65 61 66  $pagetype=="leaf
23e0: 22 20 26 26 20 24 70 61 67 65 6e 6f 21 3d 24 70  " && $pageno!=$p
23f0: 72 65 76 2b 31 7d 20 7b 0a 20 20 20 20 20 20 69  rev+1} {.      i
2400: 6e 63 72 20 67 61 70 5f 63 6e 74 0a 20 20 20 20  ncr gap_cnt.    
2410: 7d 0a 20 20 20 20 73 65 74 20 70 72 65 76 20 24  }.    set prev $
2420: 70 61 67 65 6e 6f 0a 20 20 7d 0a 20 20 6d 65 6d  pageno.  }.  mem
2430: 20 65 76 61 6c 20 7b 0a 20 20 20 20 49 4e 53 45   eval {.    INSE
2440: 52 54 20 49 4e 54 4f 20 73 70 61 63 65 5f 75 73  RT INTO space_us
2450: 65 64 20 56 41 4c 55 45 53 28 0a 20 20 20 20 20  ed VALUES(.     
2460: 20 24 6e 61 6d 65 2c 0a 20 20 20 20 20 20 24 74   $name,.      $t
2470: 62 6c 6e 61 6d 65 2c 0a 20 20 20 20 20 20 24 69  blname,.      $i
2480: 73 5f 69 6e 64 65 78 2c 0a 20 20 20 20 20 20 24  s_index,.      $
2490: 69 73 5f 77 69 74 68 6f 75 74 5f 72 6f 77 69 64  is_without_rowid
24a0: 2c 0a 20 20 20 20 20 20 24 6e 65 6e 74 72 79 2c  ,.      $nentry,
24b0: 0a 20 20 20 20 20 20 24 6c 65 61 66 5f 65 6e 74  .      $leaf_ent
24c0: 72 69 65 73 2c 0a 20 20 20 20 20 20 24 64 65 70  ries,.      $dep
24d0: 74 68 2c 0a 20 20 20 20 20 20 24 70 61 79 6c 6f  th,.      $paylo
24e0: 61 64 2c 20 20 20 20 20 0a 20 20 20 20 20 20 24  ad,     .      $
24f0: 6f 76 66 6c 5f 70 61 79 6c 6f 61 64 2c 0a 20 20  ovfl_payload,.  
2500: 20 20 20 20 24 6f 76 66 6c 5f 63 6e 74 2c 20 20      $ovfl_cnt,  
2510: 20 0a 20 20 20 20 20 20 24 6d 78 5f 70 61 79 6c   .      $mx_payl
2520: 6f 61 64 2c 0a 20 20 20 20 20 20 24 69 6e 74 5f  oad,.      $int_
2530: 70 61 67 65 73 2c 0a 20 20 20 20 20 20 24 6c 65  pages,.      $le
2540: 61 66 5f 70 61 67 65 73 2c 20 20 0a 20 20 20 20  af_pages,  .    
2550: 20 20 24 6f 76 66 6c 5f 70 61 67 65 73 2c 20 0a    $ovfl_pages, .
2560: 20 20 20 20 20 20 24 69 6e 74 5f 75 6e 75 73 65        $int_unuse
2570: 64 2c 20 0a 20 20 20 20 20 20 24 6c 65 61 66 5f  d, .      $leaf_
2580: 75 6e 75 73 65 64 2c 0a 20 20 20 20 20 20 24 6f  unused,.      $o
2590: 76 66 6c 5f 75 6e 75 73 65 64 2c 0a 20 20 20 20  vfl_unused,.    
25a0: 20 20 24 67 61 70 5f 63 6e 74 2c 0a 20 20 20 20    $gap_cnt,.    
25b0: 20 20 24 63 6f 6d 70 72 65 73 73 65 64 5f 73 69    $compressed_si
25c0: 7a 65 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 7d 0a  ze.    );.  }.}.
25d0: 0a 70 72 6f 63 20 69 6e 74 65 67 65 72 69 66 79  .proc integerify
25e0: 20 7b 72 65 61 6c 7d 20 7b 0a 20 20 69 66 20 7b   {real} {.  if {
25f0: 5b 73 74 72 69 6e 67 20 69 73 20 64 6f 75 62 6c  [string is doubl
2600: 65 20 2d 73 74 72 69 63 74 20 24 72 65 61 6c 5d  e -strict $real]
2610: 7d 20 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 5b  } {.    return [
2620: 65 78 70 72 20 7b 77 69 64 65 28 24 72 65 61 6c  expr {wide($real
2630: 29 7d 5d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20  )}].  } else {. 
2640: 20 20 20 72 65 74 75 72 6e 20 30 0a 20 20 7d 0a     return 0.  }.
2650: 7d 0a 6d 65 6d 20 66 75 6e 63 74 69 6f 6e 20 69  }.mem function i
2660: 6e 74 20 69 6e 74 65 67 65 72 69 66 79 0a 0a 23  nt integerify..#
2670: 20 51 75 6f 74 65 20 61 20 73 74 72 69 6e 67 20   Quote a string 
2680: 66 6f 72 20 75 73 65 20 69 6e 20 61 6e 20 53 51  for use in an SQ
2690: 4c 20 71 75 65 72 79 2e 20 45 78 61 6d 70 6c 65  L query. Example
26a0: 73 3a 0a 23 0a 23 20 5b 71 75 6f 74 65 20 7b 68  s:.#.# [quote {h
26b0: 65 6c 6c 6f 20 77 6f 72 6c 64 7d 5d 20 20 20 3d  ello world}]   =
26c0: 3d 20 7b 27 68 65 6c 6c 6f 20 77 6f 72 6c 64 27  = {'hello world'
26d0: 7d 0a 23 20 5b 71 75 6f 74 65 20 7b 68 65 6c 6c  }.# [quote {hell
26e0: 6f 20 77 6f 72 6c 64 27 73 7d 5d 20 3d 3d 20 7b  o world's}] == {
26f0: 27 68 65 6c 6c 6f 20 77 6f 72 6c 64 27 27 73 27  'hello world''s'
2700: 7d 0a 23 0a 70 72 6f 63 20 71 75 6f 74 65 20 7b  }.#.proc quote {
2710: 74 78 74 7d 20 7b 0a 20 20 72 65 74 75 72 6e 20  txt} {.  return 
2720: 5b 73 74 72 69 6e 67 20 6d 61 70 20 7b 27 20 27  [string map {' '
2730: 27 7d 20 24 74 78 74 5d 0a 7d 0a 0a 23 20 4f 75  '} $txt].}..# Ou
2740: 74 70 75 74 20 61 20 74 69 74 6c 65 20 6c 69 6e  tput a title lin
2750: 65 0a 23 0a 70 72 6f 63 20 74 69 74 6c 65 6c 69  e.#.proc titleli
2760: 6e 65 20 7b 74 69 74 6c 65 7d 20 7b 0a 20 20 69  ne {title} {.  i
2770: 66 20 7b 24 74 69 74 6c 65 3d 3d 22 22 7d 20 7b  f {$title==""} {
2780: 0a 20 20 20 20 70 75 74 73 20 5b 73 74 72 69 6e  .    puts [strin
2790: 67 20 72 65 70 65 61 74 20 2a 20 37 39 5d 0a 20  g repeat * 79]. 
27a0: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65   } else {.    se
27b0: 74 20 6c 65 6e 20 5b 73 74 72 69 6e 67 20 6c 65  t len [string le
27c0: 6e 67 74 68 20 24 74 69 74 6c 65 5d 0a 20 20 20  ngth $title].   
27d0: 20 73 65 74 20 73 74 61 72 73 20 5b 73 74 72 69   set stars [stri
27e0: 6e 67 20 72 65 70 65 61 74 20 2a 20 5b 65 78 70  ng repeat * [exp
27f0: 72 20 37 39 2d 24 6c 65 6e 2d 35 5d 5d 0a 20 20  r 79-$len-5]].  
2800: 20 20 70 75 74 73 20 22 2a 2a 2a 20 24 74 69 74    puts "*** $tit
2810: 6c 65 20 24 73 74 61 72 73 22 0a 20 20 7d 0a 7d  le $stars".  }.}
2820: 0a 0a 23 20 47 65 6e 65 72 61 74 65 20 61 20 73  ..# Generate a s
2830: 69 6e 67 6c 65 20 6c 69 6e 65 20 6f 66 20 6f 75  ingle line of ou
2840: 74 70 75 74 20 69 6e 20 74 68 65 20 73 74 61 74  tput in the stat
2850: 69 73 74 69 63 73 20 73 65 63 74 69 6f 6e 20 6f  istics section o
2860: 66 20 74 68 65 0a 23 20 72 65 70 6f 72 74 2e 0a  f the.# report..
2870: 23 0a 70 72 6f 63 20 73 74 61 74 6c 69 6e 65 20  #.proc statline 
2880: 7b 74 69 74 6c 65 20 76 61 6c 75 65 20 7b 65 78  {title value {ex
2890: 74 72 61 20 7b 7d 7d 7d 20 7b 0a 20 20 73 65 74  tra {}}} {.  set
28a0: 20 6c 65 6e 20 5b 73 74 72 69 6e 67 20 6c 65 6e   len [string len
28b0: 67 74 68 20 24 74 69 74 6c 65 5d 0a 20 20 73 65  gth $title].  se
28c0: 74 20 64 6f 74 73 20 5b 73 74 72 69 6e 67 20 72  t dots [string r
28d0: 65 70 65 61 74 20 2e 20 5b 65 78 70 72 20 35 30  epeat . [expr 50
28e0: 2d 24 6c 65 6e 5d 5d 0a 20 20 73 65 74 20 6c 65  -$len]].  set le
28f0: 6e 20 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68  n [string length
2900: 20 24 76 61 6c 75 65 5d 0a 20 20 73 65 74 20 73   $value].  set s
2910: 70 32 20 5b 73 74 72 69 6e 67 20 72 61 6e 67 65  p2 [string range
2920: 20 7b 20 20 20 20 20 20 20 20 20 20 7d 20 24 6c   {          } $l
2930: 65 6e 20 65 6e 64 5d 0a 20 20 69 66 20 7b 24 65  en end].  if {$e
2940: 78 74 72 61 20 6e 65 20 22 22 7d 20 7b 0a 20 20  xtra ne ""} {.  
2950: 20 20 73 65 74 20 65 78 74 72 61 20 22 20 24 65    set extra " $e
2960: 78 74 72 61 22 0a 20 20 7d 0a 20 20 70 75 74 73  xtra".  }.  puts
2970: 20 22 24 74 69 74 6c 65 24 64 6f 74 73 20 24 76   "$title$dots $v
2980: 61 6c 75 65 24 73 70 32 24 65 78 74 72 61 22 0a  alue$sp2$extra".
2990: 7d 0a 0a 23 20 47 65 6e 65 72 61 74 65 20 61 20  }..# Generate a 
29a0: 66 6f 72 6d 61 74 74 65 64 20 70 65 72 63 65 6e  formatted percen
29b0: 74 61 67 65 20 76 61 6c 75 65 20 66 6f 72 20 24  tage value for $
29c0: 6e 75 6d 2f 24 64 65 6e 6f 6d 0a 23 0a 70 72 6f  num/$denom.#.pro
29d0: 63 20 70 65 72 63 65 6e 74 20 7b 6e 75 6d 20 64  c percent {num d
29e0: 65 6e 6f 6d 20 7b 6f 66 20 7b 7d 7d 7d 20 7b 0a  enom {of {}}} {.
29f0: 20 20 69 66 20 7b 24 64 65 6e 6f 6d 3d 3d 30 2e    if {$denom==0.
2a00: 30 7d 20 7b 72 65 74 75 72 6e 20 22 22 7d 0a 20  0} {return ""}. 
2a10: 20 73 65 74 20 76 20 5b 65 78 70 72 20 7b 24 6e   set v [expr {$n
2a20: 75 6d 2a 31 30 30 2e 30 2f 24 64 65 6e 6f 6d 7d  um*100.0/$denom}
2a30: 5d 0a 20 20 73 65 74 20 6f 66 20 7b 7d 0a 20 20  ].  set of {}.  
2a40: 69 66 20 7b 24 76 3d 3d 31 30 30 2e 30 20 7c 7c  if {$v==100.0 ||
2a50: 20 24 76 3c 30 2e 30 30 31 20 7c 7c 20 28 24 76   $v<0.001 || ($v
2a60: 3e 31 2e 30 20 26 26 20 24 76 3c 39 39 2e 30 29  >1.0 && $v<99.0)
2a70: 7d 20 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 5b  } {.    return [
2a80: 66 6f 72 6d 61 74 20 7b 25 35 2e 31 66 25 25 20  format {%5.1f%% 
2a90: 25 73 7d 20 24 76 20 24 6f 66 5d 0a 20 20 7d 20  %s} $v $of].  } 
2aa0: 65 6c 73 65 69 66 20 7b 24 76 3c 30 2e 31 20 7c  elseif {$v<0.1 |
2ab0: 7c 20 24 76 3e 39 39 2e 39 7d 20 7b 0a 20 20 20  | $v>99.9} {.   
2ac0: 20 72 65 74 75 72 6e 20 5b 66 6f 72 6d 61 74 20   return [format 
2ad0: 7b 25 37 2e 33 66 25 25 20 25 73 7d 20 24 76 20  {%7.3f%% %s} $v 
2ae0: 24 6f 66 5d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a  $of].  } else {.
2af0: 20 20 20 20 72 65 74 75 72 6e 20 5b 66 6f 72 6d      return [form
2b00: 61 74 20 7b 25 36 2e 32 66 25 25 20 25 73 7d 20  at {%6.2f%% %s} 
2b10: 24 76 20 24 6f 66 5d 0a 20 20 7d 0a 7d 0a 0a 70  $v $of].  }.}..p
2b20: 72 6f 63 20 64 69 76 69 64 65 20 7b 6e 75 6d 20  roc divide {num 
2b30: 64 65 6e 6f 6d 7d 20 7b 0a 20 20 69 66 20 7b 24  denom} {.  if {$
2b40: 64 65 6e 6f 6d 3d 3d 30 7d 20 7b 72 65 74 75 72  denom==0} {retur
2b50: 6e 20 30 2e 30 7d 0a 20 20 72 65 74 75 72 6e 20  n 0.0}.  return 
2b60: 5b 66 6f 72 6d 61 74 20 25 2e 32 66 20 5b 65 78  [format %.2f [ex
2b70: 70 72 20 64 6f 75 62 6c 65 28 24 6e 75 6d 29 2f  pr double($num)/
2b80: 64 6f 75 62 6c 65 28 24 64 65 6e 6f 6d 29 5d 5d  double($denom)]]
2b90: 0a 7d 0a 0a 23 20 47 65 6e 65 72 61 74 65 20 61  .}..# Generate a
2ba0: 20 73 75 62 72 65 70 6f 72 74 20 74 68 61 74 20   subreport that 
2bb0: 63 6f 76 65 72 73 20 73 6f 6d 65 20 73 75 62 73  covers some subs
2bc0: 65 74 20 6f 66 20 74 68 65 20 64 61 74 61 62 61  et of the databa
2bd0: 73 65 2e 0a 23 20 74 68 65 20 24 77 68 65 72 65  se..# the $where
2be0: 20 63 6c 61 75 73 65 20 64 65 74 65 72 6d 69 6e   clause determin
2bf0: 65 73 20 77 68 69 63 68 20 73 75 62 73 65 74 20  es which subset 
2c00: 74 6f 20 61 6e 61 6c 79 7a 65 2e 0a 23 0a 70 72  to analyze..#.pr
2c10: 6f 63 20 73 75 62 72 65 70 6f 72 74 20 7b 74 69  oc subreport {ti
2c20: 74 6c 65 20 77 68 65 72 65 20 73 68 6f 77 46 72  tle where showFr
2c30: 61 67 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c 20 70  ag} {.  global p
2c40: 61 67 65 53 69 7a 65 20 66 69 6c 65 5f 70 67 63  ageSize file_pgc
2c50: 6e 74 20 63 6f 6d 70 72 65 73 73 4f 76 65 72 68  nt compressOverh
2c60: 65 61 64 0a 0a 20 20 23 20 51 75 65 72 79 20 74  ead..  # Query t
2c70: 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 64 61 74  he in-memory dat
2c80: 61 62 61 73 65 20 66 6f 72 20 74 68 65 20 73 75  abase for the su
2c90: 6d 20 6f 66 20 76 61 72 69 6f 75 73 20 73 74 61  m of various sta
2ca0: 74 69 73 74 69 63 73 20 0a 20 20 23 20 66 6f 72  tistics .  # for
2cb0: 20 74 68 65 20 73 75 62 73 65 74 20 6f 66 20 74   the subset of t
2cc0: 61 62 6c 65 73 2f 69 6e 64 69 63 65 73 20 69 64  ables/indices id
2cd0: 65 6e 74 69 66 69 65 64 20 62 79 20 74 68 65 20  entified by the 
2ce0: 57 48 45 52 45 20 63 6c 61 75 73 65 20 69 6e 0a  WHERE clause in.
2cf0: 20 20 23 20 24 77 68 65 72 65 2e 20 4e 6f 74 65    # $where. Note
2d00: 20 74 68 61 74 20 65 76 65 6e 20 69 66 20 74 68   that even if th
2d10: 65 20 57 48 45 52 45 20 63 6c 61 75 73 65 20 6d  e WHERE clause m
2d20: 61 74 63 68 65 73 20 6e 6f 20 72 6f 77 73 2c 20  atches no rows, 
2d30: 74 68 65 0a 20 20 23 20 66 6f 6c 6c 6f 77 69 6e  the.  # followin
2d40: 67 20 71 75 65 72 79 20 72 65 74 75 72 6e 73 20  g query returns 
2d50: 65 78 61 63 74 6c 79 20 6f 6e 65 20 72 6f 77 20  exactly one row 
2d60: 28 62 65 63 61 75 73 65 20 69 74 20 69 73 20 61  (because it is a
2d70: 6e 20 61 67 67 72 65 67 61 74 65 29 2e 0a 20 20  n aggregate)..  
2d80: 23 0a 20 20 23 20 54 68 65 20 72 65 73 75 6c 74  #.  # The result
2d90: 73 20 6f 66 20 74 68 65 20 71 75 65 72 79 20 61  s of the query a
2da0: 72 65 20 73 74 6f 72 65 64 20 64 69 72 65 63 74  re stored direct
2db0: 6c 79 20 62 79 20 53 51 4c 69 74 65 20 69 6e 74  ly by SQLite int
2dc0: 6f 20 6c 6f 63 61 6c 20 0a 20 20 23 20 76 61 72  o local .  # var
2dd0: 69 61 62 6c 65 73 20 28 69 2e 65 2e 20 24 6e 65  iables (i.e. $ne
2de0: 6e 74 72 79 2c 20 24 70 61 79 6c 6f 61 64 20 65  ntry, $payload e
2df0: 74 63 2e 29 2e 0a 20 20 23 0a 20 20 6d 65 6d 20  tc.)..  #.  mem 
2e00: 65 76 61 6c 20 22 0a 20 20 20 20 53 45 4c 45 43  eval ".    SELEC
2e10: 54 0a 20 20 20 20 20 20 69 6e 74 28 73 75 6d 28  T.      int(sum(
2e20: 0a 20 20 20 20 20 20 20 20 43 41 53 45 20 57 48  .        CASE WH
2e30: 45 4e 20 28 69 73 5f 77 69 74 68 6f 75 74 5f 72  EN (is_without_r
2e40: 6f 77 69 64 20 4f 52 20 69 73 5f 69 6e 64 65 78  owid OR is_index
2e50: 29 20 54 48 45 4e 20 6e 65 6e 74 72 79 20 0a 20  ) THEN nentry . 
2e60: 20 20 20 20 20 20 20 20 20 20 20 20 45 4c 53 45              ELSE
2e70: 20 6c 65 61 66 5f 65 6e 74 72 69 65 73 20 0a 20   leaf_entries . 
2e80: 20 20 20 20 20 20 20 45 4e 44 0a 20 20 20 20 20         END.     
2e90: 20 29 29 20 41 53 20 6e 65 6e 74 72 79 2c 0a 20   )) AS nentry,. 
2ea0: 20 20 20 20 20 69 6e 74 28 73 75 6d 28 70 61 79       int(sum(pay
2eb0: 6c 6f 61 64 29 29 20 41 53 20 70 61 79 6c 6f 61  load)) AS payloa
2ec0: 64 2c 0a 20 20 20 20 20 20 69 6e 74 28 73 75 6d  d,.      int(sum
2ed0: 28 6f 76 66 6c 5f 70 61 79 6c 6f 61 64 29 29 20  (ovfl_payload)) 
2ee0: 41 53 20 6f 76 66 6c 5f 70 61 79 6c 6f 61 64 2c  AS ovfl_payload,
2ef0: 0a 20 20 20 20 20 20 6d 61 78 28 6d 78 5f 70 61  .      max(mx_pa
2f00: 79 6c 6f 61 64 29 20 41 53 20 6d 78 5f 70 61 79  yload) AS mx_pay
2f10: 6c 6f 61 64 2c 0a 20 20 20 20 20 20 69 6e 74 28  load,.      int(
2f20: 73 75 6d 28 6f 76 66 6c 5f 63 6e 74 29 29 20 61  sum(ovfl_cnt)) a
2f30: 73 20 6f 76 66 6c 5f 63 6e 74 2c 0a 20 20 20 20  s ovfl_cnt,.    
2f40: 20 20 69 6e 74 28 73 75 6d 28 6c 65 61 66 5f 70    int(sum(leaf_p
2f50: 61 67 65 73 29 29 20 41 53 20 6c 65 61 66 5f 70  ages)) AS leaf_p
2f60: 61 67 65 73 2c 0a 20 20 20 20 20 20 69 6e 74 28  ages,.      int(
2f70: 73 75 6d 28 69 6e 74 5f 70 61 67 65 73 29 29 20  sum(int_pages)) 
2f80: 41 53 20 69 6e 74 5f 70 61 67 65 73 2c 0a 20 20  AS int_pages,.  
2f90: 20 20 20 20 69 6e 74 28 73 75 6d 28 6f 76 66 6c      int(sum(ovfl
2fa0: 5f 70 61 67 65 73 29 29 20 41 53 20 6f 76 66 6c  _pages)) AS ovfl
2fb0: 5f 70 61 67 65 73 2c 0a 20 20 20 20 20 20 69 6e  _pages,.      in
2fc0: 74 28 73 75 6d 28 6c 65 61 66 5f 75 6e 75 73 65  t(sum(leaf_unuse
2fd0: 64 29 29 20 41 53 20 6c 65 61 66 5f 75 6e 75 73  d)) AS leaf_unus
2fe0: 65 64 2c 0a 20 20 20 20 20 20 69 6e 74 28 73 75  ed,.      int(su
2ff0: 6d 28 69 6e 74 5f 75 6e 75 73 65 64 29 29 20 41  m(int_unused)) A
3000: 53 20 69 6e 74 5f 75 6e 75 73 65 64 2c 0a 20 20  S int_unused,.  
3010: 20 20 20 20 69 6e 74 28 73 75 6d 28 6f 76 66 6c      int(sum(ovfl
3020: 5f 75 6e 75 73 65 64 29 29 20 41 53 20 6f 76 66  _unused)) AS ovf
3030: 6c 5f 75 6e 75 73 65 64 2c 0a 20 20 20 20 20 20  l_unused,.      
3040: 69 6e 74 28 73 75 6d 28 67 61 70 5f 63 6e 74 29  int(sum(gap_cnt)
3050: 29 20 41 53 20 67 61 70 5f 63 6e 74 2c 0a 20 20  ) AS gap_cnt,.  
3060: 20 20 20 20 69 6e 74 28 73 75 6d 28 63 6f 6d 70      int(sum(comp
3070: 72 65 73 73 65 64 5f 73 69 7a 65 29 29 20 41 53  ressed_size)) AS
3080: 20 63 6f 6d 70 72 65 73 73 65 64 5f 73 69 7a 65   compressed_size
3090: 2c 0a 20 20 20 20 20 20 69 6e 74 28 6d 61 78 28  ,.      int(max(
30a0: 64 65 70 74 68 29 29 20 41 53 20 64 65 70 74 68  depth)) AS depth
30b0: 2c 0a 20 20 20 20 20 20 63 6f 75 6e 74 28 2a 29  ,.      count(*)
30c0: 20 41 53 20 63 6e 74 0a 20 20 20 20 46 52 4f 4d   AS cnt.    FROM
30d0: 20 73 70 61 63 65 5f 75 73 65 64 20 57 48 45 52   space_used WHER
30e0: 45 20 24 77 68 65 72 65 22 20 7b 7d 20 7b 7d 0a  E $where" {} {}.
30f0: 0a 20 20 23 20 4f 75 74 70 75 74 20 74 68 65 20  .  # Output the 
3100: 73 75 62 2d 72 65 70 6f 72 74 20 74 69 74 6c 65  sub-report title
3110: 2c 20 6e 69 63 65 6c 79 20 64 65 63 6f 72 61 74  , nicely decorat
3120: 65 64 20 77 69 74 68 20 2a 20 63 68 61 72 61 63  ed with * charac
3130: 74 65 72 73 2e 0a 20 20 23 0a 20 20 70 75 74 73  ters..  #.  puts
3140: 20 22 22 0a 20 20 74 69 74 6c 65 6c 69 6e 65 20   "".  titleline 
3150: 24 74 69 74 6c 65 0a 20 20 70 75 74 73 20 22 22  $title.  puts ""
3160: 0a 0a 20 20 23 20 43 61 6c 63 75 6c 61 74 65 20  ..  # Calculate 
3170: 73 74 61 74 69 73 74 69 63 73 20 61 6e 64 20 73  statistics and s
3180: 74 6f 72 65 20 74 68 65 20 72 65 73 75 6c 74 73  tore the results
3190: 20 69 6e 20 54 43 4c 20 76 61 72 69 61 62 6c 65   in TCL variable
31a0: 73 2c 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 20  s, as follows:. 
31b0: 20 23 0a 20 20 23 20 74 6f 74 61 6c 5f 70 61 67   #.  # total_pag
31c0: 65 73 3a 20 44 61 74 61 62 61 73 65 20 70 61 67  es: Database pag
31d0: 65 73 20 63 6f 6e 73 75 6d 65 64 2e 0a 20 20 23  es consumed..  #
31e0: 20 74 6f 74 61 6c 5f 70 61 67 65 73 5f 70 65 72   total_pages_per
31f0: 63 65 6e 74 3a 20 50 61 67 65 73 20 63 6f 6e 73  cent: Pages cons
3200: 75 6d 65 64 20 61 73 20 61 20 70 65 72 63 65 6e  umed as a percen
3210: 74 61 67 65 20 6f 66 20 74 68 65 20 66 69 6c 65  tage of the file
3220: 2e 0a 20 20 23 20 73 74 6f 72 61 67 65 3a 20 42  ..  # storage: B
3230: 79 74 65 73 20 63 6f 6e 73 75 6d 65 64 2e 0a 20  ytes consumed.. 
3240: 20 23 20 70 61 79 6c 6f 61 64 5f 70 65 72 63 65   # payload_perce
3250: 6e 74 3a 20 50 61 79 6c 6f 61 64 20 62 79 74 65  nt: Payload byte
3260: 73 20 75 73 65 64 20 61 73 20 61 20 70 65 72 63  s used as a perc
3270: 65 6e 74 61 67 65 20 6f 66 20 24 73 74 6f 72 61  entage of $stora
3280: 67 65 2e 0a 20 20 23 20 74 6f 74 61 6c 5f 75 6e  ge..  # total_un
3290: 75 73 65 64 3a 20 55 6e 75 73 65 64 20 62 79 74  used: Unused byt
32a0: 65 73 20 6f 6e 20 70 61 67 65 73 2e 0a 20 20 23  es on pages..  #
32b0: 20 61 76 67 5f 70 61 79 6c 6f 61 64 3a 20 41 76   avg_payload: Av
32c0: 65 72 61 67 65 20 70 61 79 6c 6f 61 64 20 70 65  erage payload pe
32d0: 72 20 62 74 72 65 65 20 65 6e 74 72 79 2e 0a 20  r btree entry.. 
32e0: 20 23 20 61 76 67 5f 66 61 6e 6f 75 74 3a 20 41   # avg_fanout: A
32f0: 76 65 72 61 67 65 20 66 61 6e 6f 75 74 20 66 6f  verage fanout fo
3300: 72 20 69 6e 74 65 72 6e 61 6c 20 70 61 67 65 73  r internal pages
3310: 2e 0a 20 20 23 20 61 76 67 5f 75 6e 75 73 65 64  ..  # avg_unused
3320: 3a 20 41 76 65 72 61 67 65 20 75 6e 75 73 65 64  : Average unused
3330: 20 62 79 74 65 73 20 70 65 72 20 62 74 72 65 65   bytes per btree
3340: 20 65 6e 74 72 79 2e 0a 20 20 23 20 6f 76 66 6c   entry..  # ovfl
3350: 5f 63 6e 74 5f 70 65 72 63 65 6e 74 3a 20 50 65  _cnt_percent: Pe
3360: 72 63 65 6e 74 61 67 65 20 6f 66 20 62 74 72 65  rcentage of btre
3370: 65 20 65 6e 74 72 69 65 73 20 74 68 61 74 20 75  e entries that u
3380: 73 65 20 6f 76 65 72 66 6c 6f 77 20 70 61 67 65  se overflow page
3390: 73 2e 0a 20 20 23 0a 20 20 73 65 74 20 74 6f 74  s..  #.  set tot
33a0: 61 6c 5f 70 61 67 65 73 20 5b 65 78 70 72 20 7b  al_pages [expr {
33b0: 24 6c 65 61 66 5f 70 61 67 65 73 2b 24 69 6e 74  $leaf_pages+$int
33c0: 5f 70 61 67 65 73 2b 24 6f 76 66 6c 5f 70 61 67  _pages+$ovfl_pag
33d0: 65 73 7d 5d 0a 20 20 73 65 74 20 74 6f 74 61 6c  es}].  set total
33e0: 5f 70 61 67 65 73 5f 70 65 72 63 65 6e 74 20 5b  _pages_percent [
33f0: 70 65 72 63 65 6e 74 20 24 74 6f 74 61 6c 5f 70  percent $total_p
3400: 61 67 65 73 20 24 66 69 6c 65 5f 70 67 63 6e 74  ages $file_pgcnt
3410: 5d 0a 20 20 73 65 74 20 73 74 6f 72 61 67 65 20  ].  set storage 
3420: 5b 65 78 70 72 20 7b 24 74 6f 74 61 6c 5f 70 61  [expr {$total_pa
3430: 67 65 73 2a 24 70 61 67 65 53 69 7a 65 7d 5d 0a  ges*$pageSize}].
3440: 20 20 73 65 74 20 70 61 79 6c 6f 61 64 5f 70 65    set payload_pe
3450: 72 63 65 6e 74 20 5b 70 65 72 63 65 6e 74 20 24  rcent [percent $
3460: 70 61 79 6c 6f 61 64 20 24 73 74 6f 72 61 67 65  payload $storage
3470: 20 7b 6f 66 20 73 74 6f 72 61 67 65 20 63 6f 6e   {of storage con
3480: 73 75 6d 65 64 7d 5d 0a 20 20 73 65 74 20 74 6f  sumed}].  set to
3490: 74 61 6c 5f 75 6e 75 73 65 64 20 5b 65 78 70 72  tal_unused [expr
34a0: 20 7b 24 6f 76 66 6c 5f 75 6e 75 73 65 64 2b 24   {$ovfl_unused+$
34b0: 69 6e 74 5f 75 6e 75 73 65 64 2b 24 6c 65 61 66  int_unused+$leaf
34c0: 5f 75 6e 75 73 65 64 7d 5d 0a 20 20 73 65 74 20  _unused}].  set 
34d0: 61 76 67 5f 70 61 79 6c 6f 61 64 20 5b 64 69 76  avg_payload [div
34e0: 69 64 65 20 24 70 61 79 6c 6f 61 64 20 24 6e 65  ide $payload $ne
34f0: 6e 74 72 79 5d 0a 20 20 73 65 74 20 61 76 67 5f  ntry].  set avg_
3500: 75 6e 75 73 65 64 20 5b 64 69 76 69 64 65 20 24  unused [divide $
3510: 74 6f 74 61 6c 5f 75 6e 75 73 65 64 20 24 6e 65  total_unused $ne
3520: 6e 74 72 79 5d 0a 20 20 69 66 20 7b 24 69 6e 74  ntry].  if {$int
3530: 5f 70 61 67 65 73 3e 30 7d 20 7b 0a 20 20 20 20  _pages>0} {.    
3540: 23 20 54 4f 44 4f 3a 20 49 73 20 74 68 69 73 20  # TODO: Is this 
3550: 66 6f 72 6d 75 6c 61 20 63 6f 72 72 65 63 74 3f  formula correct?
3560: 0a 20 20 20 20 73 65 74 20 6e 54 61 62 20 5b 6d  .    set nTab [m
3570: 65 6d 20 65 76 61 6c 20 22 0a 20 20 20 20 20 20  em eval ".      
3580: 53 45 4c 45 43 54 20 63 6f 75 6e 74 28 2a 29 20  SELECT count(*) 
3590: 46 52 4f 4d 20 28 0a 20 20 20 20 20 20 20 20 20  FROM (.         
35a0: 20 53 45 4c 45 43 54 20 44 49 53 54 49 4e 43 54   SELECT DISTINCT
35b0: 20 74 62 6c 6e 61 6d 65 20 46 52 4f 4d 20 73 70   tblname FROM sp
35c0: 61 63 65 5f 75 73 65 64 20 57 48 45 52 45 20 24  ace_used WHERE $
35d0: 77 68 65 72 65 20 41 4e 44 20 69 73 5f 69 6e 64  where AND is_ind
35e0: 65 78 3d 30 0a 20 20 20 20 20 20 29 0a 20 20 20  ex=0.      ).   
35f0: 20 22 5d 0a 20 20 20 20 73 65 74 20 61 76 67 5f   "].    set avg_
3600: 66 61 6e 6f 75 74 20 5b 6d 65 6d 20 65 76 61 6c  fanout [mem eval
3610: 20 22 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20   ".      SELECT 
3620: 28 73 75 6d 28 6c 65 61 66 5f 70 61 67 65 73 2b  (sum(leaf_pages+
3630: 69 6e 74 5f 70 61 67 65 73 29 2d 24 6e 54 61 62  int_pages)-$nTab
3640: 29 2f 73 75 6d 28 69 6e 74 5f 70 61 67 65 73 29  )/sum(int_pages)
3650: 20 46 52 4f 4d 20 73 70 61 63 65 5f 75 73 65 64   FROM space_used
3660: 0a 20 20 20 20 20 20 20 20 20 20 57 48 45 52 45  .          WHERE
3670: 20 24 77 68 65 72 65 0a 20 20 20 20 22 5d 0a 20   $where.    "]. 
3680: 20 20 20 73 65 74 20 61 76 67 5f 66 61 6e 6f 75     set avg_fanou
3690: 74 20 5b 66 6f 72 6d 61 74 20 25 2e 32 66 20 24  t [format %.2f $
36a0: 61 76 67 5f 66 61 6e 6f 75 74 5d 0a 20 20 7d 0a  avg_fanout].  }.
36b0: 20 20 73 65 74 20 6f 76 66 6c 5f 63 6e 74 5f 70    set ovfl_cnt_p
36c0: 65 72 63 65 6e 74 20 5b 70 65 72 63 65 6e 74 20  ercent [percent 
36d0: 24 6f 76 66 6c 5f 63 6e 74 20 24 6e 65 6e 74 72  $ovfl_cnt $nentr
36e0: 79 20 7b 6f 66 20 61 6c 6c 20 65 6e 74 72 69 65  y {of all entrie
36f0: 73 7d 5d 0a 0a 20 20 23 20 50 72 69 6e 74 20 6f  s}]..  # Print o
3700: 75 74 20 74 68 65 20 73 75 62 2d 72 65 70 6f 72  ut the sub-repor
3710: 74 20 73 74 61 74 69 73 74 69 63 73 2e 0a 20 20  t statistics..  
3720: 23 0a 20 20 73 74 61 74 6c 69 6e 65 20 7b 50 65  #.  statline {Pe
3730: 72 63 65 6e 74 61 67 65 20 6f 66 20 74 6f 74 61  rcentage of tota
3740: 6c 20 64 61 74 61 62 61 73 65 7d 20 24 74 6f 74  l database} $tot
3750: 61 6c 5f 70 61 67 65 73 5f 70 65 72 63 65 6e 74  al_pages_percent
3760: 0a 20 20 73 74 61 74 6c 69 6e 65 20 7b 4e 75 6d  .  statline {Num
3770: 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73 7d 20  ber of entries} 
3780: 24 6e 65 6e 74 72 79 0a 20 20 73 74 61 74 6c 69  $nentry.  statli
3790: 6e 65 20 7b 42 79 74 65 73 20 6f 66 20 73 74 6f  ne {Bytes of sto
37a0: 72 61 67 65 20 63 6f 6e 73 75 6d 65 64 7d 20 24  rage consumed} $
37b0: 73 74 6f 72 61 67 65 0a 20 20 69 66 20 7b 24 63  storage.  if {$c
37c0: 6f 6d 70 72 65 73 73 65 64 5f 73 69 7a 65 21 3d  ompressed_size!=
37d0: 24 73 74 6f 72 61 67 65 7d 20 7b 0a 20 20 20 20  $storage} {.    
37e0: 73 65 74 20 63 6f 6d 70 72 65 73 73 65 64 5f 73  set compressed_s
37f0: 69 7a 65 20 5b 65 78 70 72 20 7b 24 63 6f 6d 70  ize [expr {$comp
3800: 72 65 73 73 65 64 5f 73 69 7a 65 2b 24 63 6f 6d  ressed_size+$com
3810: 70 72 65 73 73 4f 76 65 72 68 65 61 64 2a 24 74  pressOverhead*$t
3820: 6f 74 61 6c 5f 70 61 67 65 73 7d 5d 0a 20 20 20  otal_pages}].   
3830: 20 73 65 74 20 70 63 74 20 5b 65 78 70 72 20 7b   set pct [expr {
3840: 24 63 6f 6d 70 72 65 73 73 65 64 5f 73 69 7a 65  $compressed_size
3850: 2a 31 30 30 2e 30 2f 24 73 74 6f 72 61 67 65 7d  *100.0/$storage}
3860: 5d 0a 20 20 20 20 73 65 74 20 70 63 74 20 5b 66  ].    set pct [f
3870: 6f 72 6d 61 74 20 7b 25 35 2e 31 66 25 25 7d 20  ormat {%5.1f%%} 
3880: 24 70 63 74 5d 0a 20 20 20 20 73 74 61 74 6c 69  $pct].    statli
3890: 6e 65 20 7b 42 79 74 65 73 20 75 73 65 64 20 61  ne {Bytes used a
38a0: 66 74 65 72 20 63 6f 6d 70 72 65 73 73 69 6f 6e  fter compression
38b0: 7d 20 24 63 6f 6d 70 72 65 73 73 65 64 5f 73 69  } $compressed_si
38c0: 7a 65 20 24 70 63 74 0a 20 20 7d 0a 20 20 73 74  ze $pct.  }.  st
38d0: 61 74 6c 69 6e 65 20 7b 42 79 74 65 73 20 6f 66  atline {Bytes of
38e0: 20 70 61 79 6c 6f 61 64 7d 20 24 70 61 79 6c 6f   payload} $paylo
38f0: 61 64 20 24 70 61 79 6c 6f 61 64 5f 70 65 72 63  ad $payload_perc
3900: 65 6e 74 0a 20 20 69 66 20 7b 24 63 6e 74 3d 3d  ent.  if {$cnt==
3910: 31 7d 20 7b 73 74 61 74 6c 69 6e 65 20 7b 42 2d  1} {statline {B-
3920: 74 72 65 65 20 64 65 70 74 68 7d 20 24 64 65 70  tree depth} $dep
3930: 74 68 7d 0a 20 20 73 74 61 74 6c 69 6e 65 20 7b  th}.  statline {
3940: 41 76 65 72 61 67 65 20 70 61 79 6c 6f 61 64 20  Average payload 
3950: 70 65 72 20 65 6e 74 72 79 7d 20 24 61 76 67 5f  per entry} $avg_
3960: 70 61 79 6c 6f 61 64 0a 20 20 73 74 61 74 6c 69  payload.  statli
3970: 6e 65 20 7b 41 76 65 72 61 67 65 20 75 6e 75 73  ne {Average unus
3980: 65 64 20 62 79 74 65 73 20 70 65 72 20 65 6e 74  ed bytes per ent
3990: 72 79 7d 20 24 61 76 67 5f 75 6e 75 73 65 64 0a  ry} $avg_unused.
39a0: 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73    if {[info exis
39b0: 74 73 20 61 76 67 5f 66 61 6e 6f 75 74 5d 7d 20  ts avg_fanout]} 
39c0: 7b 0a 20 20 20 20 73 74 61 74 6c 69 6e 65 20 7b  {.    statline {
39d0: 41 76 65 72 61 67 65 20 66 61 6e 6f 75 74 7d 20  Average fanout} 
39e0: 24 61 76 67 5f 66 61 6e 6f 75 74 0a 20 20 7d 0a  $avg_fanout.  }.
39f0: 20 20 69 66 20 7b 24 73 68 6f 77 46 72 61 67 20    if {$showFrag 
3a00: 26 26 20 24 74 6f 74 61 6c 5f 70 61 67 65 73 3e  && $total_pages>
3a10: 31 7d 20 7b 0a 20 20 20 20 73 65 74 20 66 72 61  1} {.    set fra
3a20: 67 6d 65 6e 74 61 74 69 6f 6e 20 5b 70 65 72 63  gmentation [perc
3a30: 65 6e 74 20 24 67 61 70 5f 63 6e 74 20 5b 65 78  ent $gap_cnt [ex
3a40: 70 72 20 7b 24 74 6f 74 61 6c 5f 70 61 67 65 73  pr {$total_pages
3a50: 2d 31 7d 5d 5d 0a 20 20 20 20 73 74 61 74 6c 69  -1}]].    statli
3a60: 6e 65 20 7b 4e 6f 6e 2d 73 65 71 75 65 6e 74 69  ne {Non-sequenti
3a70: 61 6c 20 70 61 67 65 73 7d 20 24 67 61 70 5f 63  al pages} $gap_c
3a80: 6e 74 20 24 66 72 61 67 6d 65 6e 74 61 74 69 6f  nt $fragmentatio
3a90: 6e 0a 20 20 7d 0a 20 20 73 74 61 74 6c 69 6e 65  n.  }.  statline
3aa0: 20 7b 4d 61 78 69 6d 75 6d 20 70 61 79 6c 6f 61   {Maximum payloa
3ab0: 64 20 70 65 72 20 65 6e 74 72 79 7d 20 24 6d 78  d per entry} $mx
3ac0: 5f 70 61 79 6c 6f 61 64 0a 20 20 73 74 61 74 6c  _payload.  statl
3ad0: 69 6e 65 20 7b 45 6e 74 72 69 65 73 20 74 68 61  ine {Entries tha
3ae0: 74 20 75 73 65 20 6f 76 65 72 66 6c 6f 77 7d 20  t use overflow} 
3af0: 24 6f 76 66 6c 5f 63 6e 74 20 24 6f 76 66 6c 5f  $ovfl_cnt $ovfl_
3b00: 63 6e 74 5f 70 65 72 63 65 6e 74 0a 20 20 69 66  cnt_percent.  if
3b10: 20 7b 24 69 6e 74 5f 70 61 67 65 73 3e 30 7d 20   {$int_pages>0} 
3b20: 7b 0a 20 20 20 20 73 74 61 74 6c 69 6e 65 20 7b  {.    statline {
3b30: 49 6e 64 65 78 20 70 61 67 65 73 20 75 73 65 64  Index pages used
3b40: 7d 20 24 69 6e 74 5f 70 61 67 65 73 0a 20 20 7d  } $int_pages.  }
3b50: 0a 20 20 73 74 61 74 6c 69 6e 65 20 7b 50 72 69  .  statline {Pri
3b60: 6d 61 72 79 20 70 61 67 65 73 20 75 73 65 64 7d  mary pages used}
3b70: 20 24 6c 65 61 66 5f 70 61 67 65 73 0a 20 20 73   $leaf_pages.  s
3b80: 74 61 74 6c 69 6e 65 20 7b 4f 76 65 72 66 6c 6f  tatline {Overflo
3b90: 77 20 70 61 67 65 73 20 75 73 65 64 7d 20 24 6f  w pages used} $o
3ba0: 76 66 6c 5f 70 61 67 65 73 0a 20 20 73 74 61 74  vfl_pages.  stat
3bb0: 6c 69 6e 65 20 7b 54 6f 74 61 6c 20 70 61 67 65  line {Total page
3bc0: 73 20 75 73 65 64 7d 20 24 74 6f 74 61 6c 5f 70  s used} $total_p
3bd0: 61 67 65 73 0a 20 20 69 66 20 7b 24 69 6e 74 5f  ages.  if {$int_
3be0: 75 6e 75 73 65 64 3e 30 7d 20 7b 0a 20 20 20 20  unused>0} {.    
3bf0: 73 65 74 20 69 6e 74 5f 75 6e 75 73 65 64 5f 70  set int_unused_p
3c00: 65 72 63 65 6e 74 20 5b 0a 20 20 20 20 20 20 20  ercent [.       
3c10: 20 20 70 65 72 63 65 6e 74 20 24 69 6e 74 5f 75    percent $int_u
3c20: 6e 75 73 65 64 20 5b 65 78 70 72 20 7b 24 69 6e  nused [expr {$in
3c30: 74 5f 70 61 67 65 73 2a 24 70 61 67 65 53 69 7a  t_pages*$pageSiz
3c40: 65 7d 5d 20 7b 6f 66 20 69 6e 64 65 78 20 73 70  e}] {of index sp
3c50: 61 63 65 7d 5d 0a 20 20 20 20 73 74 61 74 6c 69  ace}].    statli
3c60: 6e 65 20 22 55 6e 75 73 65 64 20 62 79 74 65 73  ne "Unused bytes
3c70: 20 6f 6e 20 69 6e 64 65 78 20 70 61 67 65 73 22   on index pages"
3c80: 20 24 69 6e 74 5f 75 6e 75 73 65 64 20 24 69 6e   $int_unused $in
3c90: 74 5f 75 6e 75 73 65 64 5f 70 65 72 63 65 6e 74  t_unused_percent
3ca0: 0a 20 20 7d 0a 20 20 73 74 61 74 6c 69 6e 65 20  .  }.  statline 
3cb0: 22 55 6e 75 73 65 64 20 62 79 74 65 73 20 6f 6e  "Unused bytes on
3cc0: 20 70 72 69 6d 61 72 79 20 70 61 67 65 73 22 20   primary pages" 
3cd0: 24 6c 65 61 66 5f 75 6e 75 73 65 64 20 5b 0a 20  $leaf_unused [. 
3ce0: 20 20 20 20 70 65 72 63 65 6e 74 20 24 6c 65 61      percent $lea
3cf0: 66 5f 75 6e 75 73 65 64 20 5b 65 78 70 72 20 7b  f_unused [expr {
3d00: 24 6c 65 61 66 5f 70 61 67 65 73 2a 24 70 61 67  $leaf_pages*$pag
3d10: 65 53 69 7a 65 7d 5d 20 7b 6f 66 20 70 72 69 6d  eSize}] {of prim
3d20: 61 72 79 20 73 70 61 63 65 7d 5d 0a 20 20 73 74  ary space}].  st
3d30: 61 74 6c 69 6e 65 20 22 55 6e 75 73 65 64 20 62  atline "Unused b
3d40: 79 74 65 73 20 6f 6e 20 6f 76 65 72 66 6c 6f 77  ytes on overflow
3d50: 20 70 61 67 65 73 22 20 24 6f 76 66 6c 5f 75 6e   pages" $ovfl_un
3d60: 75 73 65 64 20 5b 0a 20 20 20 20 20 70 65 72 63  used [.     perc
3d70: 65 6e 74 20 24 6f 76 66 6c 5f 75 6e 75 73 65 64  ent $ovfl_unused
3d80: 20 5b 65 78 70 72 20 7b 24 6f 76 66 6c 5f 70 61   [expr {$ovfl_pa
3d90: 67 65 73 2a 24 70 61 67 65 53 69 7a 65 7d 5d 20  ges*$pageSize}] 
3da0: 7b 6f 66 20 6f 76 65 72 66 6c 6f 77 20 73 70 61  {of overflow spa
3db0: 63 65 7d 5d 0a 20 20 73 74 61 74 6c 69 6e 65 20  ce}].  statline 
3dc0: 22 55 6e 75 73 65 64 20 62 79 74 65 73 20 6f 6e  "Unused bytes on
3dd0: 20 61 6c 6c 20 70 61 67 65 73 22 20 24 74 6f 74   all pages" $tot
3de0: 61 6c 5f 75 6e 75 73 65 64 20 5b 0a 20 20 20 20  al_unused [.    
3df0: 20 20 20 20 20 20 20 20 20 20 20 70 65 72 63 65             perce
3e00: 6e 74 20 24 74 6f 74 61 6c 5f 75 6e 75 73 65 64  nt $total_unused
3e10: 20 24 73 74 6f 72 61 67 65 20 7b 6f 66 20 61 6c   $storage {of al
3e20: 6c 20 73 70 61 63 65 7d 5d 0a 20 20 72 65 74 75  l space}].  retu
3e30: 72 6e 20 31 0a 7d 0a 0a 23 20 43 61 6c 63 75 6c  rn 1.}..# Calcul
3e40: 61 74 65 20 74 68 65 20 6f 76 65 72 68 65 61 64  ate the overhead
3e50: 20 69 6e 20 70 61 67 65 73 20 63 61 75 73 65 64   in pages caused
3e60: 20 62 79 20 61 75 74 6f 2d 76 61 63 75 75 6d 2e   by auto-vacuum.
3e70: 20 0a 23 0a 23 20 54 68 69 73 20 70 72 6f 63 65   .#.# This proce
3e80: 64 75 72 65 20 63 61 6c 63 75 6c 61 74 65 73 20  dure calculates 
3e90: 61 6e 64 20 72 65 74 75 72 6e 73 20 74 68 65 20  and returns the 
3ea0: 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  number of pages 
3eb0: 75 73 65 64 20 62 79 20 74 68 65 20 0a 23 20 61  used by the .# a
3ec0: 75 74 6f 2d 76 61 63 75 75 6d 20 27 70 6f 69 6e  uto-vacuum 'poin
3ed0: 74 65 72 2d 6d 61 70 27 2e 20 49 66 20 74 68 65  ter-map'. If the
3ee0: 20 64 61 74 61 62 61 73 65 20 64 6f 65 73 20 6e   database does n
3ef0: 6f 74 20 73 75 70 70 6f 72 74 20 61 75 74 6f 2d  ot support auto-
3f00: 76 61 63 75 75 6d 2c 0a 23 20 74 68 65 6e 20 30  vacuum,.# then 0
3f10: 20 69 73 20 72 65 74 75 72 6e 65 64 2e 20 54 68   is returned. Th
3f20: 65 20 74 77 6f 20 61 72 67 75 6d 65 6e 74 73 20  e two arguments 
3f30: 61 72 65 20 74 68 65 20 73 69 7a 65 20 6f 66 20  are the size of 
3f40: 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
3f50: 65 20 69 6e 0a 23 20 70 61 67 65 73 20 61 6e 64  e in.# pages and
3f60: 20 74 68 65 20 70 61 67 65 20 73 69 7a 65 20 75   the page size u
3f70: 73 65 64 20 62 79 20 74 68 65 20 64 61 74 61 62  sed by the datab
3f80: 61 73 65 20 28 69 6e 20 62 79 74 65 73 29 2e 0a  ase (in bytes)..
3f90: 70 72 6f 63 20 61 75 74 6f 76 61 63 75 75 6d 5f  proc autovacuum_
3fa0: 6f 76 65 72 68 65 61 64 20 7b 66 69 6c 65 50 61  overhead {filePa
3fb0: 67 65 73 20 70 61 67 65 53 69 7a 65 7d 20 7b 0a  ges pageSize} {.
3fc0: 0a 20 20 23 20 53 65 74 20 24 61 75 74 6f 76 61  .  # Set $autova
3fd0: 63 75 75 6d 20 74 6f 20 6e 6f 6e 2d 7a 65 72 6f  cuum to non-zero
3fe0: 20 66 6f 72 20 64 61 74 61 62 61 73 65 73 20 74   for databases t
3ff0: 68 61 74 20 73 75 70 70 6f 72 74 20 61 75 74 6f  hat support auto
4000: 2d 76 61 63 75 75 6d 2e 0a 20 20 73 65 74 20 61  -vacuum..  set a
4010: 75 74 6f 76 61 63 75 75 6d 20 5b 64 62 20 6f 6e  utovacuum [db on
4020: 65 20 7b 50 52 41 47 4d 41 20 61 75 74 6f 5f 76  e {PRAGMA auto_v
4030: 61 63 75 75 6d 7d 5d 0a 0a 20 20 23 20 49 66 20  acuum}]..  # If 
4040: 74 68 65 20 64 61 74 61 62 61 73 65 20 69 73 20  the database is 
4050: 6e 6f 74 20 61 6e 20 61 75 74 6f 2d 76 61 63 75  not an auto-vacu
4060: 75 6d 20 64 61 74 61 62 61 73 65 20 6f 72 20 74  um database or t
4070: 68 65 20 66 69 6c 65 20 63 6f 6e 73 69 73 74 73  he file consists
4080: 0a 20 20 23 20 6f 66 20 6f 6e 65 20 70 61 67 65  .  # of one page
4090: 20 6f 6e 6c 79 20 74 68 65 6e 20 74 68 65 72 65   only then there
40a0: 20 69 73 20 6e 6f 20 6f 76 65 72 68 65 61 64 20   is no overhead 
40b0: 66 6f 72 20 61 75 74 6f 2d 76 61 63 75 75 6d 2e  for auto-vacuum.
40c0: 20 52 65 74 75 72 6e 20 7a 65 72 6f 2e 0a 20 20   Return zero..  
40d0: 69 66 20 7b 30 3d 3d 24 61 75 74 6f 76 61 63 75  if {0==$autovacu
40e0: 75 6d 20 7c 7c 20 24 66 69 6c 65 50 61 67 65 73  um || $filePages
40f0: 3d 3d 31 7d 20 7b 0a 20 20 20 20 72 65 74 75 72  ==1} {.    retur
4100: 6e 20 30 0a 20 20 7d 0a 0a 20 20 23 20 54 68 65  n 0.  }..  # The
4110: 20 6e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69   number of entri
4120: 65 73 20 6f 6e 20 65 61 63 68 20 70 6f 69 6e 74  es on each point
4130: 65 72 20 6d 61 70 20 70 61 67 65 2e 20 54 68 65  er map page. The
4140: 20 6c 61 79 6f 75 74 20 6f 66 20 74 68 65 0a 20   layout of the. 
4150: 20 23 20 64 61 74 61 62 61 73 65 20 66 69 6c 65   # database file
4160: 20 69 73 20 6f 6e 65 20 70 6f 69 6e 74 65 72 2d   is one pointer-
4170: 6d 61 70 20 70 61 67 65 2c 20 66 6f 6c 6c 6f 77  map page, follow
4180: 65 64 20 62 79 20 24 70 74 72 73 50 65 72 50 61  ed by $ptrsPerPa
4190: 67 65 20 6f 74 68 65 72 0a 20 20 23 20 70 61 67  ge other.  # pag
41a0: 65 73 2c 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20  es, followed by 
41b0: 61 20 70 6f 69 6e 74 65 72 2d 6d 61 70 20 70 61  a pointer-map pa
41c0: 67 65 20 65 74 63 2e 20 54 68 65 20 66 69 72 73  ge etc. The firs
41d0: 74 20 70 6f 69 6e 74 65 72 2d 6d 61 70 20 70 61  t pointer-map pa
41e0: 67 65 0a 20 20 23 20 69 73 20 74 68 65 20 73 65  ge.  # is the se
41f0: 63 6f 6e 64 20 70 61 67 65 20 6f 66 20 74 68 65  cond page of the
4200: 20 66 69 6c 65 20 6f 76 65 72 61 6c 6c 2e 0a 20   file overall.. 
4210: 20 73 65 74 20 70 74 72 73 50 65 72 50 61 67 65   set ptrsPerPage
4220: 20 5b 65 78 70 72 20 64 6f 75 62 6c 65 28 24 70   [expr double($p
4230: 61 67 65 53 69 7a 65 2f 35 29 5d 0a 0a 20 20 23  ageSize/5)]..  #
4240: 20 52 65 74 75 72 6e 20 74 68 65 20 6e 75 6d 62   Return the numb
4250: 65 72 20 6f 66 20 70 6f 69 6e 74 65 72 20 6d 61  er of pointer ma
4260: 70 20 70 61 67 65 73 20 69 6e 20 74 68 65 20 64  p pages in the d
4270: 61 74 61 62 61 73 65 2e 0a 20 20 72 65 74 75 72  atabase..  retur
4280: 6e 20 5b 65 78 70 72 20 77 69 64 65 28 63 65 69  n [expr wide(cei
4290: 6c 28 20 28 24 66 69 6c 65 50 61 67 65 73 2d 31  l( ($filePages-1
42a0: 2e 30 29 2f 28 24 70 74 72 73 50 65 72 50 61 67  .0)/($ptrsPerPag
42b0: 65 2b 31 2e 30 29 20 29 29 5d 0a 7d 0a 0a 0a 23  e+1.0) ))].}...#
42c0: 20 43 61 6c 63 75 6c 61 74 65 20 74 68 65 20 73   Calculate the s
42d0: 75 6d 6d 61 72 79 20 73 74 61 74 69 73 74 69 63  ummary statistic
42e0: 73 20 66 6f 72 20 74 68 65 20 64 61 74 61 62 61  s for the databa
42f0: 73 65 20 61 6e 64 20 73 74 6f 72 65 20 74 68 65  se and store the
4300: 20 72 65 73 75 6c 74 73 0a 23 20 69 6e 20 54 43   results.# in TC
4310: 4c 20 76 61 72 69 61 62 6c 65 73 2e 20 54 68 65  L variables. The
4320: 79 20 61 72 65 20 6f 75 74 70 75 74 20 62 65 6c  y are output bel
4330: 6f 77 2e 20 56 61 72 69 61 62 6c 65 73 20 61 72  ow. Variables ar
4340: 65 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 23 0a  e as follows:.#.
4350: 23 20 70 61 67 65 53 69 7a 65 3a 20 20 20 20 20  # pageSize:     
4360: 20 53 69 7a 65 20 6f 66 20 65 61 63 68 20 70 61   Size of each pa
4370: 67 65 20 69 6e 20 62 79 74 65 73 2e 0a 23 20 66  ge in bytes..# f
4380: 69 6c 65 5f 62 79 74 65 73 3a 20 20 20 20 46 69  ile_bytes:    Fi
4390: 6c 65 20 73 69 7a 65 20 69 6e 20 62 79 74 65 73  le size in bytes
43a0: 2e 0a 23 20 66 69 6c 65 5f 70 67 63 6e 74 3a 20  ..# file_pgcnt: 
43b0: 20 20 20 4e 75 6d 62 65 72 20 6f 66 20 70 61 67     Number of pag
43c0: 65 73 20 69 6e 20 74 68 65 20 66 69 6c 65 2e 0a  es in the file..
43d0: 23 20 66 69 6c 65 5f 70 67 63 6e 74 32 3a 20 20  # file_pgcnt2:  
43e0: 20 4e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73   Number of pages
43f0: 20 69 6e 20 74 68 65 20 66 69 6c 65 20 28 63 61   in the file (ca
4400: 6c 63 75 6c 61 74 65 64 29 2e 0a 23 20 61 76 5f  lculated)..# av_
4410: 70 67 63 6e 74 3a 20 20 20 20 20 20 50 61 67 65  pgcnt:      Page
4420: 73 20 63 6f 6e 73 75 6d 65 64 20 62 79 20 74 68  s consumed by th
4430: 65 20 61 75 74 6f 2d 76 61 63 75 75 6d 20 70 6f  e auto-vacuum po
4440: 69 6e 74 65 72 2d 6d 61 70 2e 0a 23 20 61 76 5f  inter-map..# av_
4450: 70 65 72 63 65 6e 74 3a 20 20 20 20 50 65 72 63  percent:    Perc
4460: 65 6e 74 61 67 65 20 6f 66 20 74 68 65 20 66 69  entage of the fi
4470: 6c 65 20 63 6f 6e 73 75 6d 65 64 20 62 79 20 61  le consumed by a
4480: 75 74 6f 2d 76 61 63 75 75 6d 20 70 6f 69 6e 74  uto-vacuum point
4490: 65 72 2d 6d 61 70 2e 0a 23 20 69 6e 75 73 65 5f  er-map..# inuse_
44a0: 70 67 63 6e 74 3a 20 20 20 44 61 74 61 20 70 61  pgcnt:   Data pa
44b0: 67 65 73 20 69 6e 20 74 68 65 20 66 69 6c 65 2e  ges in the file.
44c0: 0a 23 20 69 6e 75 73 65 5f 70 65 72 63 65 6e 74  .# inuse_percent
44d0: 3a 20 50 65 72 63 65 6e 74 61 67 65 20 6f 66 20  : Percentage of 
44e0: 70 61 67 65 73 20 75 73 65 64 20 74 6f 20 73 74  pages used to st
44f0: 6f 72 65 20 64 61 74 61 2e 0a 23 20 66 72 65 65  ore data..# free
4500: 5f 70 67 63 6e 74 3a 20 20 20 20 46 72 65 65 20  _pgcnt:    Free 
4510: 70 61 67 65 73 20 63 61 6c 63 75 6c 61 74 65 64  pages calculated
4520: 20 61 73 20 28 3c 74 6f 74 61 6c 20 70 61 67 65   as (<total page
4530: 73 3e 20 2d 20 3c 69 6e 2d 75 73 65 20 70 61 67  s> - <in-use pag
4540: 65 73 3e 29 0a 23 20 66 72 65 65 5f 70 67 63 6e  es>).# free_pgcn
4550: 74 32 3a 20 20 20 46 72 65 65 20 70 61 67 65 73  t2:   Free pages
4560: 20 69 6e 20 74 68 65 20 66 69 6c 65 20 61 63 63   in the file acc
4570: 6f 72 64 69 6e 67 20 74 6f 20 74 68 65 20 66 69  ording to the fi
4580: 6c 65 20 68 65 61 64 65 72 2e 0a 23 20 66 72 65  le header..# fre
4590: 65 5f 70 65 72 63 65 6e 74 3a 20 20 50 65 72 63  e_percent:  Perc
45a0: 65 6e 74 61 67 65 20 6f 66 20 66 69 6c 65 20 63  entage of file c
45b0: 6f 6e 73 75 6d 65 64 20 62 79 20 66 72 65 65 20  onsumed by free 
45c0: 70 61 67 65 73 20 28 63 61 6c 63 75 6c 61 74 65  pages (calculate
45d0: 64 29 2e 0a 23 20 66 72 65 65 5f 70 65 72 63 65  d)..# free_perce
45e0: 6e 74 32 3a 20 50 65 72 63 65 6e 74 61 67 65 20  nt2: Percentage 
45f0: 6f 66 20 66 69 6c 65 20 63 6f 6e 73 75 6d 65 64  of file consumed
4600: 20 62 79 20 66 72 65 65 20 70 61 67 65 73 20 28   by free pages (
4610: 68 65 61 64 65 72 29 2e 0a 23 20 6e 74 61 62 6c  header)..# ntabl
4620: 65 3a 20 20 20 20 20 20 20 20 4e 75 6d 62 65 72  e:        Number
4630: 20 6f 66 20 74 61 62 6c 65 73 20 69 6e 20 74 68   of tables in th
4640: 65 20 64 62 2e 0a 23 20 6e 69 6e 64 65 78 3a 20  e db..# nindex: 
4650: 20 20 20 20 20 20 20 4e 75 6d 62 65 72 20 6f 66         Number of
4660: 20 69 6e 64 69 63 65 73 20 69 6e 20 74 68 65 20   indices in the 
4670: 64 62 2e 0a 23 20 6e 61 75 74 6f 69 6e 64 65 78  db..# nautoindex
4680: 3a 20 20 20 20 4e 75 6d 62 65 72 20 6f 66 20 69  :    Number of i
4690: 6e 64 69 63 65 73 20 63 72 65 61 74 65 64 20 61  ndices created a
46a0: 75 74 6f 6d 61 74 69 63 61 6c 6c 79 2e 0a 23 20  utomatically..# 
46b0: 6e 6d 61 6e 69 6e 64 65 78 3a 20 20 20 20 20 4e  nmanindex:     N
46c0: 75 6d 62 65 72 20 6f 66 20 69 6e 64 69 63 65 73  umber of indices
46d0: 20 63 72 65 61 74 65 64 20 6d 61 6e 75 61 6c 6c   created manuall
46e0: 79 2e 0a 23 20 75 73 65 72 5f 70 61 79 6c 6f 61  y..# user_payloa
46f0: 64 3a 20 20 4e 75 6d 62 65 72 20 6f 66 20 62 79  d:  Number of by
4700: 74 65 73 20 6f 66 20 70 61 79 6c 6f 61 64 20 69  tes of payload i
4710: 6e 20 74 61 62 6c 65 20 62 74 72 65 65 73 20 0a  n table btrees .
4720: 23 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  #               
4730: 20 28 6e 6f 74 20 69 6e 63 6c 75 64 69 6e 67 20   (not including 
4740: 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 29 0a 23  sqlite_master).#
4750: 20 75 73 65 72 5f 70 65 72 63 65 6e 74 3a 20 20   user_percent:  
4760: 24 75 73 65 72 5f 70 61 79 6c 6f 61 64 20 61 73  $user_payload as
4770: 20 61 20 70 65 72 63 65 6e 74 61 67 65 20 6f 66   a percentage of
4780: 20 74 6f 74 61 6c 20 66 69 6c 65 20 73 69 7a 65   total file size
4790: 2e 0a 0a 23 23 23 20 54 68 65 20 66 6f 6c 6c 6f  ...### The follo
47a0: 77 69 6e 67 2c 20 73 65 74 74 69 6e 67 20 24 66  wing, setting $f
47b0: 69 6c 65 5f 62 79 74 65 73 20 62 61 73 65 64 20  ile_bytes based 
47c0: 6f 6e 20 74 68 65 20 61 63 74 75 61 6c 20 73 69  on the actual si
47d0: 7a 65 20 6f 66 20 74 68 65 20 66 69 6c 65 0a 23  ze of the file.#
47e0: 23 23 20 6f 6e 20 64 69 73 6b 2c 20 63 61 75 73  ## on disk, caus
47f0: 65 73 20 74 68 69 73 20 74 6f 6f 6c 20 74 6f 20  es this tool to 
4800: 63 68 6f 6b 65 20 6f 6e 20 7a 69 70 76 66 73 20  choke on zipvfs 
4810: 64 61 74 61 62 61 73 65 73 2e 20 53 6f 20 73 65  databases. So se
4820: 74 20 69 74 20 62 61 73 65 64 0a 23 23 23 20 6f  t it based.### o
4830: 6e 20 74 68 65 20 72 65 74 75 72 6e 20 6f 66 20  n the return of 
4840: 5b 50 52 41 47 4d 41 20 70 61 67 65 5f 63 6f 75  [PRAGMA page_cou
4850: 6e 74 5d 20 69 6e 73 74 65 61 64 2e 0a 69 66 20  nt] instead..if 
4860: 30 20 7b 0a 20 20 73 65 74 20 66 69 6c 65 5f 62  0 {.  set file_b
4870: 79 74 65 73 20 20 5b 66 69 6c 65 20 73 69 7a 65  ytes  [file size
4880: 20 24 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a   $file_to_analyz
4890: 65 5d 0a 20 20 73 65 74 20 66 69 6c 65 5f 70 67  e].  set file_pg
48a0: 63 6e 74 20 20 5b 65 78 70 72 20 7b 24 66 69 6c  cnt  [expr {$fil
48b0: 65 5f 62 79 74 65 73 2f 24 70 61 67 65 53 69 7a  e_bytes/$pageSiz
48c0: 65 7d 5d 0a 7d 0a 73 65 74 20 66 69 6c 65 5f 70  e}].}.set file_p
48d0: 67 63 6e 74 20 20 5b 64 62 20 6f 6e 65 20 7b 50  gcnt  [db one {P
48e0: 52 41 47 4d 41 20 70 61 67 65 5f 63 6f 75 6e 74  RAGMA page_count
48f0: 7d 5d 0a 73 65 74 20 66 69 6c 65 5f 62 79 74 65  }].set file_byte
4900: 73 20 20 5b 65 78 70 72 20 7b 24 66 69 6c 65 5f  s  [expr {$file_
4910: 70 67 63 6e 74 20 2a 20 24 70 61 67 65 53 69 7a  pgcnt * $pageSiz
4920: 65 7d 5d 0a 0a 73 65 74 20 61 76 5f 70 67 63 6e  e}]..set av_pgcn
4930: 74 20 20 20 20 5b 61 75 74 6f 76 61 63 75 75 6d  t    [autovacuum
4940: 5f 6f 76 65 72 68 65 61 64 20 24 66 69 6c 65 5f  _overhead $file_
4950: 70 67 63 6e 74 20 24 70 61 67 65 53 69 7a 65 5d  pgcnt $pageSize]
4960: 0a 73 65 74 20 61 76 5f 70 65 72 63 65 6e 74 20  .set av_percent 
4970: 20 5b 70 65 72 63 65 6e 74 20 24 61 76 5f 70 67   [percent $av_pg
4980: 63 6e 74 20 24 66 69 6c 65 5f 70 67 63 6e 74 5d  cnt $file_pgcnt]
4990: 0a 0a 73 65 74 20 73 71 6c 20 7b 53 45 4c 45 43  ..set sql {SELEC
49a0: 54 20 73 75 6d 28 6c 65 61 66 5f 70 61 67 65 73  T sum(leaf_pages
49b0: 2b 69 6e 74 5f 70 61 67 65 73 2b 6f 76 66 6c 5f  +int_pages+ovfl_
49c0: 70 61 67 65 73 29 20 46 52 4f 4d 20 73 70 61 63  pages) FROM spac
49d0: 65 5f 75 73 65 64 7d 0a 73 65 74 20 69 6e 75 73  e_used}.set inus
49e0: 65 5f 70 67 63 6e 74 20 20 20 5b 65 78 70 72 20  e_pgcnt   [expr 
49f0: 77 69 64 65 28 5b 6d 65 6d 20 65 76 61 6c 20 24  wide([mem eval $
4a00: 73 71 6c 5d 29 5d 0a 73 65 74 20 69 6e 75 73 65  sql])].set inuse
4a10: 5f 70 65 72 63 65 6e 74 20 5b 70 65 72 63 65 6e  _percent [percen
4a20: 74 20 24 69 6e 75 73 65 5f 70 67 63 6e 74 20 24  t $inuse_pgcnt $
4a30: 66 69 6c 65 5f 70 67 63 6e 74 5d 0a 0a 73 65 74  file_pgcnt]..set
4a40: 20 66 72 65 65 5f 70 67 63 6e 74 20 20 20 20 5b   free_pgcnt    [
4a50: 65 78 70 72 20 7b 24 66 69 6c 65 5f 70 67 63 6e  expr {$file_pgcn
4a60: 74 2d 24 69 6e 75 73 65 5f 70 67 63 6e 74 2d 24  t-$inuse_pgcnt-$
4a70: 61 76 5f 70 67 63 6e 74 7d 5d 0a 73 65 74 20 66  av_pgcnt}].set f
4a80: 72 65 65 5f 70 65 72 63 65 6e 74 20 20 5b 70 65  ree_percent  [pe
4a90: 72 63 65 6e 74 20 24 66 72 65 65 5f 70 67 63 6e  rcent $free_pgcn
4aa0: 74 20 24 66 69 6c 65 5f 70 67 63 6e 74 5d 0a 73  t $file_pgcnt].s
4ab0: 65 74 20 66 72 65 65 5f 70 67 63 6e 74 32 20 20  et free_pgcnt2  
4ac0: 20 5b 64 62 20 6f 6e 65 20 7b 50 52 41 47 4d 41   [db one {PRAGMA
4ad0: 20 66 72 65 65 6c 69 73 74 5f 63 6f 75 6e 74 7d   freelist_count}
4ae0: 5d 0a 73 65 74 20 66 72 65 65 5f 70 65 72 63 65  ].set free_perce
4af0: 6e 74 32 20 5b 70 65 72 63 65 6e 74 20 24 66 72  nt2 [percent $fr
4b00: 65 65 5f 70 67 63 6e 74 32 20 24 66 69 6c 65 5f  ee_pgcnt2 $file_
4b10: 70 67 63 6e 74 5d 0a 0a 73 65 74 20 66 69 6c 65  pgcnt]..set file
4b20: 5f 70 67 63 6e 74 32 20 5b 65 78 70 72 20 7b 24  _pgcnt2 [expr {$
4b30: 69 6e 75 73 65 5f 70 67 63 6e 74 2b 24 66 72 65  inuse_pgcnt+$fre
4b40: 65 5f 70 67 63 6e 74 32 2b 24 61 76 5f 70 67 63  e_pgcnt2+$av_pgc
4b50: 6e 74 7d 5d 0a 0a 73 65 74 20 6e 74 61 62 6c 65  nt}]..set ntable
4b60: 20 5b 64 62 20 65 76 61 6c 20 7b 53 45 4c 45 43   [db eval {SELEC
4b70: 54 20 63 6f 75 6e 74 28 2a 29 2b 31 20 46 52 4f  T count(*)+1 FRO
4b80: 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20  M sqlite_master 
4b90: 57 48 45 52 45 20 74 79 70 65 3d 27 74 61 62 6c  WHERE type='tabl
4ba0: 65 27 7d 5d 0a 73 65 74 20 6e 69 6e 64 65 78 20  e'}].set nindex 
4bb0: 5b 64 62 20 65 76 61 6c 20 7b 53 45 4c 45 43 54  [db eval {SELECT
4bc0: 20 63 6f 75 6e 74 28 2a 29 20 46 52 4f 4d 20 73   count(*) FROM s
4bd0: 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48 45  qlite_master WHE
4be0: 52 45 20 74 79 70 65 3d 27 69 6e 64 65 78 27 7d  RE type='index'}
4bf0: 5d 0a 73 65 74 20 73 71 6c 20 7b 53 45 4c 45 43  ].set sql {SELEC
4c00: 54 20 63 6f 75 6e 74 28 2a 29 20 46 52 4f 4d 20  T count(*) FROM 
4c10: 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48  sqlite_master WH
4c20: 45 52 45 20 6e 61 6d 65 20 4c 49 4b 45 20 27 73  ERE name LIKE 's
4c30: 71 6c 69 74 65 5f 61 75 74 6f 69 6e 64 65 78 25  qlite_autoindex%
4c40: 27 7d 0a 73 65 74 20 6e 61 75 74 6f 69 6e 64 65  '}.set nautoinde
4c50: 78 20 5b 64 62 20 65 76 61 6c 20 24 73 71 6c 5d  x [db eval $sql]
4c60: 0a 73 65 74 20 6e 6d 61 6e 69 6e 64 65 78 20 5b  .set nmanindex [
4c70: 65 78 70 72 20 7b 24 6e 69 6e 64 65 78 2d 24 6e  expr {$nindex-$n
4c80: 61 75 74 6f 69 6e 64 65 78 7d 5d 0a 0a 23 20 73  autoindex}]..# s
4c90: 65 74 20 74 6f 74 61 6c 5f 70 61 79 6c 6f 61 64  et total_payload
4ca0: 20 5b 6d 65 6d 20 65 76 61 6c 20 22 53 45 4c 45   [mem eval "SELE
4cb0: 43 54 20 73 75 6d 28 70 61 79 6c 6f 61 64 29 20  CT sum(payload) 
4cc0: 46 52 4f 4d 20 73 70 61 63 65 5f 75 73 65 64 22  FROM space_used"
4cd0: 5d 0a 73 65 74 20 75 73 65 72 5f 70 61 79 6c 6f  ].set user_paylo
4ce0: 61 64 20 5b 6d 65 6d 20 6f 6e 65 20 7b 53 45 4c  ad [mem one {SEL
4cf0: 45 43 54 20 69 6e 74 28 73 75 6d 28 70 61 79 6c  ECT int(sum(payl
4d00: 6f 61 64 29 29 20 46 52 4f 4d 20 73 70 61 63 65  oad)) FROM space
4d10: 5f 75 73 65 64 0a 20 20 20 20 20 57 48 45 52 45  _used.     WHERE
4d20: 20 4e 4f 54 20 69 73 5f 69 6e 64 65 78 20 41 4e   NOT is_index AN
4d30: 44 20 6e 61 6d 65 20 4e 4f 54 20 4c 49 4b 45 20  D name NOT LIKE 
4d40: 27 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 27 7d  'sqlite_master'}
4d50: 5d 0a 73 65 74 20 75 73 65 72 5f 70 65 72 63 65  ].set user_perce
4d60: 6e 74 20 5b 70 65 72 63 65 6e 74 20 24 75 73 65  nt [percent $use
4d70: 72 5f 70 61 79 6c 6f 61 64 20 24 66 69 6c 65 5f  r_payload $file_
4d80: 62 79 74 65 73 5d 0a 0a 23 20 4f 75 74 70 75 74  bytes]..# Output
4d90: 20 74 68 65 20 73 75 6d 6d 61 72 79 20 73 74 61   the summary sta
4da0: 74 69 73 74 69 63 73 20 63 61 6c 63 75 6c 61 74  tistics calculat
4db0: 65 64 20 61 62 6f 76 65 2e 0a 23 0a 70 75 74 73  ed above..#.puts
4dc0: 20 22 2f 2a 2a 20 44 69 73 6b 2d 53 70 61 63 65   "/** Disk-Space
4dd0: 20 55 74 69 6c 69 7a 61 74 69 6f 6e 20 52 65 70   Utilization Rep
4de0: 6f 72 74 20 46 6f 72 20 24 72 6f 6f 74 5f 66 69  ort For $root_fi
4df0: 6c 65 6e 61 6d 65 22 0a 70 75 74 73 20 22 22 0a  lename".puts "".
4e00: 73 74 61 74 6c 69 6e 65 20 7b 50 61 67 65 20 73  statline {Page s
4e10: 69 7a 65 20 69 6e 20 62 79 74 65 73 7d 20 24 70  ize in bytes} $p
4e20: 61 67 65 53 69 7a 65 0a 73 74 61 74 6c 69 6e 65  ageSize.statline
4e30: 20 7b 50 61 67 65 73 20 69 6e 20 74 68 65 20 77   {Pages in the w
4e40: 68 6f 6c 65 20 66 69 6c 65 20 28 6d 65 61 73 75  hole file (measu
4e50: 72 65 64 29 7d 20 24 66 69 6c 65 5f 70 67 63 6e  red)} $file_pgcn
4e60: 74 0a 73 74 61 74 6c 69 6e 65 20 7b 50 61 67 65  t.statline {Page
4e70: 73 20 69 6e 20 74 68 65 20 77 68 6f 6c 65 20 66  s in the whole f
4e80: 69 6c 65 20 28 63 61 6c 63 75 6c 61 74 65 64 29  ile (calculated)
4e90: 7d 20 24 66 69 6c 65 5f 70 67 63 6e 74 32 0a 73  } $file_pgcnt2.s
4ea0: 74 61 74 6c 69 6e 65 20 7b 50 61 67 65 73 20 74  tatline {Pages t
4eb0: 68 61 74 20 73 74 6f 72 65 20 64 61 74 61 7d 20  hat store data} 
4ec0: 24 69 6e 75 73 65 5f 70 67 63 6e 74 20 24 69 6e  $inuse_pgcnt $in
4ed0: 75 73 65 5f 70 65 72 63 65 6e 74 0a 73 74 61 74  use_percent.stat
4ee0: 6c 69 6e 65 20 7b 50 61 67 65 73 20 6f 6e 20 74  line {Pages on t
4ef0: 68 65 20 66 72 65 65 6c 69 73 74 20 28 70 65 72  he freelist (per
4f00: 20 68 65 61 64 65 72 29 7d 20 24 66 72 65 65 5f   header)} $free_
4f10: 70 67 63 6e 74 32 20 24 66 72 65 65 5f 70 65 72  pgcnt2 $free_per
4f20: 63 65 6e 74 32 0a 73 74 61 74 6c 69 6e 65 20 7b  cent2.statline {
4f30: 50 61 67 65 73 20 6f 6e 20 74 68 65 20 66 72 65  Pages on the fre
4f40: 65 6c 69 73 74 20 28 63 61 6c 63 75 6c 61 74 65  elist (calculate
4f50: 64 29 7d 20 24 66 72 65 65 5f 70 67 63 6e 74 20  d)} $free_pgcnt 
4f60: 24 66 72 65 65 5f 70 65 72 63 65 6e 74 0a 73 74  $free_percent.st
4f70: 61 74 6c 69 6e 65 20 7b 50 61 67 65 73 20 6f 66  atline {Pages of
4f80: 20 61 75 74 6f 2d 76 61 63 75 75 6d 20 6f 76 65   auto-vacuum ove
4f90: 72 68 65 61 64 7d 20 24 61 76 5f 70 67 63 6e 74  rhead} $av_pgcnt
4fa0: 20 24 61 76 5f 70 65 72 63 65 6e 74 0a 73 74 61   $av_percent.sta
4fb0: 74 6c 69 6e 65 20 7b 4e 75 6d 62 65 72 20 6f 66  tline {Number of
4fc0: 20 74 61 62 6c 65 73 20 69 6e 20 74 68 65 20 64   tables in the d
4fd0: 61 74 61 62 61 73 65 7d 20 24 6e 74 61 62 6c 65  atabase} $ntable
4fe0: 0a 73 74 61 74 6c 69 6e 65 20 7b 4e 75 6d 62 65  .statline {Numbe
4ff0: 72 20 6f 66 20 69 6e 64 69 63 65 73 7d 20 24 6e  r of indices} $n
5000: 69 6e 64 65 78 0a 73 74 61 74 6c 69 6e 65 20 7b  index.statline {
5010: 4e 75 6d 62 65 72 20 6f 66 20 64 65 66 69 6e 65  Number of define
5020: 64 20 69 6e 64 69 63 65 73 7d 20 24 6e 6d 61 6e  d indices} $nman
5030: 69 6e 64 65 78 0a 73 74 61 74 6c 69 6e 65 20 7b  index.statline {
5040: 4e 75 6d 62 65 72 20 6f 66 20 69 6d 70 6c 69 65  Number of implie
5050: 64 20 69 6e 64 69 63 65 73 7d 20 24 6e 61 75 74  d indices} $naut
5060: 6f 69 6e 64 65 78 0a 69 66 20 7b 24 69 73 43 6f  oindex.if {$isCo
5070: 6d 70 72 65 73 73 65 64 7d 20 7b 0a 20 20 73 74  mpressed} {.  st
5080: 61 74 6c 69 6e 65 20 7b 53 69 7a 65 20 6f 66 20  atline {Size of 
5090: 75 6e 63 6f 6d 70 72 65 73 73 65 64 20 63 6f 6e  uncompressed con
50a0: 74 65 6e 74 20 69 6e 20 62 79 74 65 73 7d 20 24  tent in bytes} $
50b0: 66 69 6c 65 5f 62 79 74 65 73 0a 20 20 73 65 74  file_bytes.  set
50c0: 20 65 66 66 69 63 69 65 6e 63 79 20 5b 70 65 72   efficiency [per
50d0: 63 65 6e 74 20 24 74 72 75 65 5f 66 69 6c 65 5f  cent $true_file_
50e0: 73 69 7a 65 20 24 66 69 6c 65 5f 62 79 74 65 73  size $file_bytes
50f0: 5d 0a 20 20 73 74 61 74 6c 69 6e 65 20 7b 53 69  ].  statline {Si
5100: 7a 65 20 6f 66 20 63 6f 6d 70 72 65 73 73 65 64  ze of compressed
5110: 20 66 69 6c 65 20 6f 6e 20 64 69 73 6b 7d 20 24   file on disk} $
5120: 74 72 75 65 5f 66 69 6c 65 5f 73 69 7a 65 20 24  true_file_size $
5130: 65 66 66 69 63 69 65 6e 63 79 0a 7d 20 65 6c 73  efficiency.} els
5140: 65 20 7b 0a 20 20 73 74 61 74 6c 69 6e 65 20 7b  e {.  statline {
5150: 53 69 7a 65 20 6f 66 20 74 68 65 20 66 69 6c 65  Size of the file
5160: 20 69 6e 20 62 79 74 65 73 7d 20 24 66 69 6c 65   in bytes} $file
5170: 5f 62 79 74 65 73 0a 7d 0a 73 74 61 74 6c 69 6e  _bytes.}.statlin
5180: 65 20 7b 42 79 74 65 73 20 6f 66 20 75 73 65 72  e {Bytes of user
5190: 20 70 61 79 6c 6f 61 64 20 73 74 6f 72 65 64 7d   payload stored}
51a0: 20 24 75 73 65 72 5f 70 61 79 6c 6f 61 64 20 24   $user_payload $
51b0: 75 73 65 72 5f 70 65 72 63 65 6e 74 0a 0a 23 20  user_percent..# 
51c0: 4f 75 74 70 75 74 20 74 61 62 6c 65 20 72 61 6e  Output table ran
51d0: 6b 69 6e 67 73 0a 23 0a 70 75 74 73 20 22 22 0a  kings.#.puts "".
51e0: 74 69 74 6c 65 6c 69 6e 65 20 22 50 61 67 65 20  titleline "Page 
51f0: 63 6f 75 6e 74 73 20 66 6f 72 20 61 6c 6c 20 74  counts for all t
5200: 61 62 6c 65 73 20 77 69 74 68 20 74 68 65 69 72  ables with their
5210: 20 69 6e 64 69 63 65 73 22 0a 70 75 74 73 20 22   indices".puts "
5220: 22 0a 6d 65 6d 20 65 76 61 6c 20 7b 53 45 4c 45  ".mem eval {SELE
5230: 43 54 20 74 62 6c 6e 61 6d 65 2c 20 63 6f 75 6e  CT tblname, coun
5240: 74 28 2a 29 20 41 53 20 63 6e 74 2c 20 0a 20 20  t(*) AS cnt, .  
5250: 20 20 20 20 20 20 20 20 20 20 20 20 69 6e 74 28              int(
5260: 73 75 6d 28 69 6e 74 5f 70 61 67 65 73 2b 6c 65  sum(int_pages+le
5270: 61 66 5f 70 61 67 65 73 2b 6f 76 66 6c 5f 70 61  af_pages+ovfl_pa
5280: 67 65 73 29 29 20 41 53 20 73 69 7a 65 0a 20 20  ges)) AS size.  
5290: 20 20 20 20 20 20 20 20 46 52 4f 4d 20 73 70 61          FROM spa
52a0: 63 65 5f 75 73 65 64 20 47 52 4f 55 50 20 42 59  ce_used GROUP BY
52b0: 20 74 62 6c 6e 61 6d 65 20 4f 52 44 45 52 20 42   tblname ORDER B
52c0: 59 20 73 69 7a 65 2b 30 20 44 45 53 43 2c 20 74  Y size+0 DESC, t
52d0: 62 6c 6e 61 6d 65 7d 20 7b 7d 20 7b 0a 20 20 73  blname} {} {.  s
52e0: 74 61 74 6c 69 6e 65 20 5b 73 74 72 69 6e 67 20  tatline [string 
52f0: 74 6f 75 70 70 65 72 20 24 74 62 6c 6e 61 6d 65  toupper $tblname
5300: 5d 20 24 73 69 7a 65 20 5b 70 65 72 63 65 6e 74  ] $size [percent
5310: 20 24 73 69 7a 65 20 24 66 69 6c 65 5f 70 67 63   $size $file_pgc
5320: 6e 74 5d 0a 7d 0a 70 75 74 73 20 22 22 0a 74 69  nt].}.puts "".ti
5330: 74 6c 65 6c 69 6e 65 20 22 50 61 67 65 20 63 6f  tleline "Page co
5340: 75 6e 74 73 20 66 6f 72 20 61 6c 6c 20 74 61 62  unts for all tab
5350: 6c 65 73 20 61 6e 64 20 69 6e 64 69 63 65 73 20  les and indices 
5360: 73 65 70 61 72 61 74 65 6c 79 22 0a 70 75 74 73  separately".puts
5370: 20 22 22 0a 6d 65 6d 20 65 76 61 6c 20 7b 0a 20   "".mem eval {. 
5380: 20 53 45 4c 45 43 54 0a 20 20 20 20 20 20 20 75   SELECT.       u
5390: 70 70 65 72 28 6e 61 6d 65 29 20 41 53 20 6e 6d  pper(name) AS nm
53a0: 2c 0a 20 20 20 20 20 20 20 69 6e 74 28 69 6e 74  ,.       int(int
53b0: 5f 70 61 67 65 73 2b 6c 65 61 66 5f 70 61 67 65  _pages+leaf_page
53c0: 73 2b 6f 76 66 6c 5f 70 61 67 65 73 29 20 41 53  s+ovfl_pages) AS
53d0: 20 73 69 7a 65 0a 20 20 20 20 46 52 4f 4d 20 73   size.    FROM s
53e0: 70 61 63 65 5f 75 73 65 64 0a 20 20 20 4f 52 44  pace_used.   ORD
53f0: 45 52 20 42 59 20 73 69 7a 65 2b 30 20 44 45 53  ER BY size+0 DES
5400: 43 2c 20 6e 61 6d 65 7d 20 7b 7d 20 7b 0a 20 20  C, name} {} {.  
5410: 73 74 61 74 6c 69 6e 65 20 24 6e 6d 20 24 73 69  statline $nm $si
5420: 7a 65 20 5b 70 65 72 63 65 6e 74 20 24 73 69 7a  ze [percent $siz
5430: 65 20 24 66 69 6c 65 5f 70 67 63 6e 74 5d 0a 7d  e $file_pgcnt].}
5440: 0a 69 66 20 7b 24 69 73 43 6f 6d 70 72 65 73 73  .if {$isCompress
5450: 65 64 7d 20 7b 0a 20 20 70 75 74 73 20 22 22 0a  ed} {.  puts "".
5460: 20 20 74 69 74 6c 65 6c 69 6e 65 20 22 42 79 74    titleline "Byt
5470: 65 73 20 6f 66 20 64 69 73 6b 20 73 70 61 63 65  es of disk space
5480: 20 75 73 65 64 20 61 66 74 65 72 20 63 6f 6d 70   used after comp
5490: 72 65 73 73 69 6f 6e 22 0a 20 20 70 75 74 73 20  ression".  puts 
54a0: 22 22 0a 20 20 73 65 74 20 63 73 75 6d 20 30 0a  "".  set csum 0.
54b0: 20 20 6d 65 6d 20 65 76 61 6c 20 7b 53 45 4c 45    mem eval {SELE
54c0: 43 54 20 74 62 6c 6e 61 6d 65 2c 0a 20 20 20 20  CT tblname,.    
54d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 6e                in
54e0: 74 28 73 75 6d 28 63 6f 6d 70 72 65 73 73 65 64  t(sum(compressed
54f0: 5f 73 69 7a 65 29 29 20 2b 0a 20 20 20 20 20 20  _size)) +.      
5500: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5510: 20 20 20 24 63 6f 6d 70 72 65 73 73 4f 76 65 72     $compressOver
5520: 68 65 61 64 2a 73 75 6d 28 69 6e 74 5f 70 61 67  head*sum(int_pag
5530: 65 73 2b 6c 65 61 66 5f 70 61 67 65 73 2b 6f 76  es+leaf_pages+ov
5540: 66 6c 5f 70 61 67 65 73 29 0a 20 20 20 20 20 20  fl_pages).      
5550: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5560: 20 20 41 53 20 63 73 69 7a 65 0a 20 20 20 20 20    AS csize.     
5570: 20 20 20 20 20 46 52 4f 4d 20 73 70 61 63 65 5f       FROM space_
5580: 75 73 65 64 20 47 52 4f 55 50 20 42 59 20 74 62  used GROUP BY tb
5590: 6c 6e 61 6d 65 20 4f 52 44 45 52 20 42 59 20 63  lname ORDER BY c
55a0: 73 69 7a 65 2b 30 20 44 45 53 43 2c 20 74 62 6c  size+0 DESC, tbl
55b0: 6e 61 6d 65 7d 20 7b 7d 20 7b 0a 20 20 20 20 69  name} {} {.    i
55c0: 6e 63 72 20 63 73 75 6d 20 24 63 73 69 7a 65 0a  ncr csum $csize.
55d0: 20 20 20 20 73 74 61 74 6c 69 6e 65 20 5b 73 74      statline [st
55e0: 72 69 6e 67 20 74 6f 75 70 70 65 72 20 24 74 62  ring toupper $tb
55f0: 6c 6e 61 6d 65 5d 20 24 63 73 69 7a 65 20 5b 70  lname] $csize [p
5600: 65 72 63 65 6e 74 20 24 63 73 69 7a 65 20 24 74  ercent $csize $t
5610: 72 75 65 5f 66 69 6c 65 5f 73 69 7a 65 5d 0a 20  rue_file_size]. 
5620: 20 7d 0a 20 20 73 65 74 20 6f 76 65 72 68 65 61   }.  set overhea
5630: 64 20 5b 65 78 70 72 20 7b 24 74 72 75 65 5f 66  d [expr {$true_f
5640: 69 6c 65 5f 73 69 7a 65 20 2d 20 24 63 73 75 6d  ile_size - $csum
5650: 7d 5d 0a 20 20 69 66 20 7b 24 6f 76 65 72 68 65  }].  if {$overhe
5660: 61 64 3e 30 7d 20 7b 0a 20 20 20 20 73 74 61 74  ad>0} {.    stat
5670: 6c 69 6e 65 20 7b 48 65 61 64 65 72 20 61 6e 64  line {Header and
5680: 20 66 72 65 65 20 73 70 61 63 65 7d 20 24 6f 76   free space} $ov
5690: 65 72 68 65 61 64 20 5b 70 65 72 63 65 6e 74 20  erhead [percent 
56a0: 24 6f 76 65 72 68 65 61 64 20 24 74 72 75 65 5f  $overhead $true_
56b0: 66 69 6c 65 5f 73 69 7a 65 5d 0a 20 20 7d 0a 7d  file_size].  }.}
56c0: 0a 0a 23 20 4f 75 74 70 75 74 20 73 75 62 72 65  ..# Output subre
56d0: 70 6f 72 74 73 0a 23 0a 69 66 20 7b 24 6e 69 6e  ports.#.if {$nin
56e0: 64 65 78 3e 30 7d 20 7b 0a 20 20 73 75 62 72 65  dex>0} {.  subre
56f0: 70 6f 72 74 20 7b 41 6c 6c 20 74 61 62 6c 65 73  port {All tables
5700: 20 61 6e 64 20 69 6e 64 69 63 65 73 7d 20 31 20   and indices} 1 
5710: 30 0a 7d 0a 73 75 62 72 65 70 6f 72 74 20 7b 41  0.}.subreport {A
5720: 6c 6c 20 74 61 62 6c 65 73 7d 20 7b 4e 4f 54 20  ll tables} {NOT 
5730: 69 73 5f 69 6e 64 65 78 7d 20 30 0a 69 66 20 7b  is_index} 0.if {
5740: 24 6e 69 6e 64 65 78 3e 30 7d 20 7b 0a 20 20 73  $nindex>0} {.  s
5750: 75 62 72 65 70 6f 72 74 20 7b 41 6c 6c 20 69 6e  ubreport {All in
5760: 64 69 63 65 73 7d 20 7b 69 73 5f 69 6e 64 65 78  dices} {is_index
5770: 7d 20 30 0a 7d 0a 66 6f 72 65 61 63 68 20 74 62  } 0.}.foreach tb
5780: 6c 20 5b 6d 65 6d 20 65 76 61 6c 20 7b 53 45 4c  l [mem eval {SEL
5790: 45 43 54 20 44 49 53 54 49 4e 43 54 20 74 62 6c  ECT DISTINCT tbl
57a0: 6e 61 6d 65 20 6e 61 6d 65 20 46 52 4f 4d 20 73  name name FROM s
57b0: 70 61 63 65 5f 75 73 65 64 0a 20 20 20 20 20 20  pace_used.      
57c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
57d0: 20 4f 52 44 45 52 20 42 59 20 6e 61 6d 65 7d 5d   ORDER BY name}]
57e0: 20 7b 0a 20 20 73 65 74 20 71 6e 20 5b 71 75 6f   {.  set qn [quo
57f0: 74 65 20 24 74 62 6c 5d 0a 20 20 73 65 74 20 6e  te $tbl].  set n
5800: 61 6d 65 20 5b 73 74 72 69 6e 67 20 74 6f 75 70  ame [string toup
5810: 70 65 72 20 24 74 62 6c 5d 0a 20 20 73 65 74 20  per $tbl].  set 
5820: 6e 20 5b 6d 65 6d 20 65 76 61 6c 20 7b 53 45 4c  n [mem eval {SEL
5830: 45 43 54 20 63 6f 75 6e 74 28 2a 29 20 46 52 4f  ECT count(*) FRO
5840: 4d 20 73 70 61 63 65 5f 75 73 65 64 20 57 48 45  M space_used WHE
5850: 52 45 20 74 62 6c 6e 61 6d 65 3d 24 74 62 6c 7d  RE tblname=$tbl}
5860: 5d 0a 20 20 69 66 20 7b 24 6e 3e 31 7d 20 7b 0a  ].  if {$n>1} {.
5870: 20 20 20 20 73 65 74 20 69 64 78 6c 69 73 74 20      set idxlist 
5880: 5b 6d 65 6d 20 65 76 61 6c 20 22 53 45 4c 45 43  [mem eval "SELEC
5890: 54 20 6e 61 6d 65 20 46 52 4f 4d 20 73 70 61 63  T name FROM spac
58a0: 65 5f 75 73 65 64 0a 20 20 20 20 20 20 20 20 20  e_used.         
58b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
58c0: 20 20 20 57 48 45 52 45 20 74 62 6c 6e 61 6d 65     WHERE tblname
58d0: 3d 27 24 71 6e 27 20 41 4e 44 20 69 73 5f 69 6e  ='$qn' AND is_in
58e0: 64 65 78 0a 20 20 20 20 20 20 20 20 20 20 20 20  dex.            
58f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5900: 4f 52 44 45 52 20 42 59 20 31 22 5d 0a 20 20 20  ORDER BY 1"].   
5910: 20 73 75 62 72 65 70 6f 72 74 20 22 54 61 62 6c   subreport "Tabl
5920: 65 20 24 6e 61 6d 65 20 61 6e 64 20 61 6c 6c 20  e $name and all 
5930: 69 74 73 20 69 6e 64 69 63 65 73 22 20 22 74 62  its indices" "tb
5940: 6c 6e 61 6d 65 3d 27 24 71 6e 27 22 20 30 0a 20  lname='$qn'" 0. 
5950: 20 20 20 73 75 62 72 65 70 6f 72 74 20 22 54 61     subreport "Ta
5960: 62 6c 65 20 24 6e 61 6d 65 20 77 2f 6f 20 61 6e  ble $name w/o an
5970: 79 20 69 6e 64 69 63 65 73 22 20 22 6e 61 6d 65  y indices" "name
5980: 3d 27 24 71 6e 27 22 20 31 0a 20 20 20 20 69 66  ='$qn'" 1.    if
5990: 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 69 64 78 6c   {[llength $idxl
59a0: 69 73 74 5d 3e 31 7d 20 7b 0a 20 20 20 20 20 20  ist]>1} {.      
59b0: 73 75 62 72 65 70 6f 72 74 20 22 49 6e 64 69 63  subreport "Indic
59c0: 65 73 20 6f 66 20 74 61 62 6c 65 20 24 6e 61 6d  es of table $nam
59d0: 65 22 20 22 74 62 6c 6e 61 6d 65 3d 27 24 71 6e  e" "tblname='$qn
59e0: 27 20 41 4e 44 20 69 73 5f 69 6e 64 65 78 22 20  ' AND is_index" 
59f0: 30 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f 72 65  0.    }.    fore
5a00: 61 63 68 20 69 64 78 20 24 69 64 78 6c 69 73 74  ach idx $idxlist
5a10: 20 7b 0a 20 20 20 20 20 20 73 65 74 20 71 69 64   {.      set qid
5a20: 78 20 5b 71 75 6f 74 65 20 24 69 64 78 5d 0a 20  x [quote $idx]. 
5a30: 20 20 20 20 20 73 75 62 72 65 70 6f 72 74 20 22       subreport "
5a40: 49 6e 64 65 78 20 5b 73 74 72 69 6e 67 20 74 6f  Index [string to
5a50: 75 70 70 65 72 20 24 69 64 78 5d 20 6f 66 20 74  upper $idx] of t
5a60: 61 62 6c 65 20 24 6e 61 6d 65 22 20 22 6e 61 6d  able $name" "nam
5a70: 65 3d 27 24 71 69 64 78 27 22 20 31 0a 20 20 20  e='$qidx'" 1.   
5a80: 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20   }.  } else {.  
5a90: 20 20 73 75 62 72 65 70 6f 72 74 20 22 54 61 62    subreport "Tab
5aa0: 6c 65 20 24 6e 61 6d 65 22 20 22 6e 61 6d 65 3d  le $name" "name=
5ab0: 27 24 71 6e 27 22 20 31 0a 20 20 7d 0a 7d 0a 0a  '$qn'" 1.  }.}..
5ac0: 23 20 4f 75 74 70 75 74 20 69 6e 73 74 72 75 63  # Output instruc
5ad0: 74 69 6f 6e 73 20 6f 6e 20 77 68 61 74 20 74 68  tions on what th
5ae0: 65 20 6e 75 6d 62 65 72 73 20 61 62 6f 76 65 20  e numbers above 
5af0: 6d 65 61 6e 2e 0a 23 0a 70 75 74 73 20 22 22 0a  mean..#.puts "".
5b00: 74 69 74 6c 65 6c 69 6e 65 20 44 65 66 69 6e 69  titleline Defini
5b10: 74 69 6f 6e 73 0a 70 75 74 73 20 7b 0a 50 61 67  tions.puts {.Pag
5b20: 65 20 73 69 7a 65 20 69 6e 20 62 79 74 65 73 0a  e size in bytes.
5b30: 0a 20 20 20 20 54 68 65 20 6e 75 6d 62 65 72 20  .    The number 
5b40: 6f 66 20 62 79 74 65 73 20 69 6e 20 61 20 73 69  of bytes in a si
5b50: 6e 67 6c 65 20 70 61 67 65 20 6f 66 20 74 68 65  ngle page of the
5b60: 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 2e 20   database file. 
5b70: 20 0a 20 20 20 20 55 73 75 61 6c 6c 79 20 31 30   .    Usually 10
5b80: 32 34 2e 0a 0a 4e 75 6d 62 65 72 20 6f 66 20 70  24...Number of p
5b90: 61 67 65 73 20 69 6e 20 74 68 65 20 77 68 6f 6c  ages in the whol
5ba0: 65 20 66 69 6c 65 0a 7d 0a 70 75 74 73 20 22 20  e file.}.puts " 
5bb0: 20 20 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66     The number of
5bc0: 20 24 70 61 67 65 53 69 7a 65 2d 62 79 74 65 20   $pageSize-byte 
5bd0: 70 61 67 65 73 20 74 68 61 74 20 67 6f 20 69 6e  pages that go in
5be0: 74 6f 20 66 6f 72 6d 69 6e 67 20 74 68 65 20 63  to forming the c
5bf0: 6f 6d 70 6c 65 74 65 0a 20 20 20 20 64 61 74 61  omplete.    data
5c00: 62 61 73 65 22 0a 70 75 74 73 20 7b 0a 50 61 67  base".puts {.Pag
5c10: 65 73 20 74 68 61 74 20 73 74 6f 72 65 20 64 61  es that store da
5c20: 74 61 0a 0a 20 20 20 20 54 68 65 20 6e 75 6d 62  ta..    The numb
5c30: 65 72 20 6f 66 20 70 61 67 65 73 20 74 68 61 74  er of pages that
5c40: 20 73 74 6f 72 65 20 64 61 74 61 2c 20 65 69 74   store data, eit
5c50: 68 65 72 20 61 73 20 70 72 69 6d 61 72 79 20 42  her as primary B
5c60: 2a 54 72 65 65 20 70 61 67 65 73 20 6f 72 0a 20  *Tree pages or. 
5c70: 20 20 20 61 73 20 6f 76 65 72 66 6c 6f 77 20 70     as overflow p
5c80: 61 67 65 73 2e 20 20 54 68 65 20 6e 75 6d 62 65  ages.  The numbe
5c90: 72 20 61 74 20 74 68 65 20 72 69 67 68 74 20 69  r at the right i
5ca0: 73 20 74 68 65 20 64 61 74 61 20 70 61 67 65 73  s the data pages
5cb0: 20 64 69 76 69 64 65 64 20 62 79 0a 20 20 20 20   divided by.    
5cc0: 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72  the total number
5cd0: 20 6f 66 20 70 61 67 65 73 20 69 6e 20 74 68 65   of pages in the
5ce0: 20 66 69 6c 65 2e 0a 0a 50 61 67 65 73 20 6f 6e   file...Pages on
5cf0: 20 74 68 65 20 66 72 65 65 6c 69 73 74 0a 0a 20   the freelist.. 
5d00: 20 20 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66     The number of
5d10: 20 70 61 67 65 73 20 74 68 61 74 20 61 72 65 20   pages that are 
5d20: 6e 6f 74 20 63 75 72 72 65 6e 74 6c 79 20 69 6e  not currently in
5d30: 20 75 73 65 20 62 75 74 20 61 72 65 20 72 65 73   use but are res
5d40: 65 72 76 65 64 20 66 6f 72 0a 20 20 20 20 66 75  erved for.    fu
5d50: 74 75 72 65 20 75 73 65 2e 20 20 54 68 65 20 70  ture use.  The p
5d60: 65 72 63 65 6e 74 61 67 65 20 61 74 20 74 68 65  ercentage at the
5d70: 20 72 69 67 68 74 20 69 73 20 74 68 65 20 6e 75   right is the nu
5d80: 6d 62 65 72 20 6f 66 20 66 72 65 65 6c 69 73 74  mber of freelist
5d90: 20 70 61 67 65 73 0a 20 20 20 20 64 69 76 69 64   pages.    divid
5da0: 65 64 20 62 79 20 74 68 65 20 74 6f 74 61 6c 20  ed by the total 
5db0: 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  number of pages 
5dc0: 69 6e 20 74 68 65 20 66 69 6c 65 2e 0a 0a 50 61  in the file...Pa
5dd0: 67 65 73 20 6f 66 20 61 75 74 6f 2d 76 61 63 75  ges of auto-vacu
5de0: 75 6d 20 6f 76 65 72 68 65 61 64 0a 0a 20 20 20  um overhead..   
5df0: 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70   The number of p
5e00: 61 67 65 73 20 74 68 61 74 20 73 74 6f 72 65 20  ages that store 
5e10: 64 61 74 61 20 75 73 65 64 20 62 79 20 74 68 65  data used by the
5e20: 20 64 61 74 61 62 61 73 65 20 74 6f 20 66 61 63   database to fac
5e30: 69 6c 69 74 61 74 65 0a 20 20 20 20 61 75 74 6f  ilitate.    auto
5e40: 2d 76 61 63 75 75 6d 2e 20 54 68 69 73 20 69 73  -vacuum. This is
5e50: 20 7a 65 72 6f 20 66 6f 72 20 64 61 74 61 62 61   zero for databa
5e60: 73 65 73 20 74 68 61 74 20 64 6f 20 6e 6f 74 20  ses that do not 
5e70: 73 75 70 70 6f 72 74 20 61 75 74 6f 2d 76 61 63  support auto-vac
5e80: 75 75 6d 2e 0a 0a 4e 75 6d 62 65 72 20 6f 66 20  uum...Number of 
5e90: 74 61 62 6c 65 73 20 69 6e 20 74 68 65 20 64 61  tables in the da
5ea0: 74 61 62 61 73 65 0a 0a 20 20 20 20 54 68 65 20  tabase..    The 
5eb0: 6e 75 6d 62 65 72 20 6f 66 20 74 61 62 6c 65 73  number of tables
5ec0: 20 69 6e 20 74 68 65 20 64 61 74 61 62 61 73 65   in the database
5ed0: 2c 20 69 6e 63 6c 75 64 69 6e 67 20 74 68 65 20  , including the 
5ee0: 53 51 4c 49 54 45 5f 4d 41 53 54 45 52 20 74 61  SQLITE_MASTER ta
5ef0: 62 6c 65 0a 20 20 20 20 75 73 65 64 20 74 6f 20  ble.    used to 
5f00: 73 74 6f 72 65 20 73 63 68 65 6d 61 20 69 6e 66  store schema inf
5f10: 6f 72 6d 61 74 69 6f 6e 2e 0a 0a 4e 75 6d 62 65  ormation...Numbe
5f20: 72 20 6f 66 20 69 6e 64 69 63 65 73 0a 0a 20 20  r of indices..  
5f30: 20 20 54 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62    The total numb
5f40: 65 72 20 6f 66 20 69 6e 64 69 63 65 73 20 69 6e  er of indices in
5f50: 20 74 68 65 20 64 61 74 61 62 61 73 65 2e 0a 0a   the database...
5f60: 4e 75 6d 62 65 72 20 6f 66 20 64 65 66 69 6e 65  Number of define
5f70: 64 20 69 6e 64 69 63 65 73 0a 0a 20 20 20 20 54  d indices..    T
5f80: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 69 6e 64  he number of ind
5f90: 69 63 65 73 20 63 72 65 61 74 65 64 20 75 73 69  ices created usi
5fa0: 6e 67 20 61 6e 20 65 78 70 6c 69 63 69 74 20 43  ng an explicit C
5fb0: 52 45 41 54 45 20 49 4e 44 45 58 20 73 74 61 74  REATE INDEX stat
5fc0: 65 6d 65 6e 74 2e 0a 0a 4e 75 6d 62 65 72 20 6f  ement...Number o
5fd0: 66 20 69 6d 70 6c 69 65 64 20 69 6e 64 69 63 65  f implied indice
5fe0: 73 0a 0a 20 20 20 20 54 68 65 20 6e 75 6d 62 65  s..    The numbe
5ff0: 72 20 6f 66 20 69 6e 64 69 63 65 73 20 75 73 65  r of indices use
6000: 64 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74 20 50  d to implement P
6010: 52 49 4d 41 52 59 20 4b 45 59 20 6f 72 20 55 4e  RIMARY KEY or UN
6020: 49 51 55 45 20 63 6f 6e 73 74 72 61 69 6e 74 73  IQUE constraints
6030: 0a 20 20 20 20 6f 6e 20 74 61 62 6c 65 73 2e 0a  .    on tables..
6040: 0a 53 69 7a 65 20 6f 66 20 74 68 65 20 66 69 6c  .Size of the fil
6050: 65 20 69 6e 20 62 79 74 65 73 0a 0a 20 20 20 20  e in bytes..    
6060: 54 68 65 20 74 6f 74 61 6c 20 61 6d 6f 75 6e 74  The total amount
6070: 20 6f 66 20 64 69 73 6b 20 73 70 61 63 65 20 75   of disk space u
6080: 73 65 64 20 62 79 20 74 68 65 20 65 6e 74 69 72  sed by the entir
6090: 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 73  e database files
60a0: 2e 0a 0a 42 79 74 65 73 20 6f 66 20 75 73 65 72  ...Bytes of user
60b0: 20 70 61 79 6c 6f 61 64 20 73 74 6f 72 65 64 0a   payload stored.
60c0: 0a 20 20 20 20 54 68 65 20 74 6f 74 61 6c 20 6e  .    The total n
60d0: 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 6f  umber of bytes o
60e0: 66 20 75 73 65 72 20 70 61 79 6c 6f 61 64 20 73  f user payload s
60f0: 74 6f 72 65 64 20 69 6e 20 74 68 65 20 64 61 74  tored in the dat
6100: 61 62 61 73 65 2e 20 54 68 65 0a 20 20 20 20 73  abase. The.    s
6110: 63 68 65 6d 61 20 69 6e 66 6f 72 6d 61 74 69 6f  chema informatio
6120: 6e 20 69 6e 20 74 68 65 20 53 51 4c 49 54 45 5f  n in the SQLITE_
6130: 4d 41 53 54 45 52 20 74 61 62 6c 65 20 69 73 20  MASTER table is 
6140: 6e 6f 74 20 63 6f 75 6e 74 65 64 20 77 68 65 6e  not counted when
6150: 0a 20 20 20 20 63 6f 6d 70 75 74 69 6e 67 20 74  .    computing t
6160: 68 69 73 20 6e 75 6d 62 65 72 2e 20 20 54 68 65  his number.  The
6170: 20 70 65 72 63 65 6e 74 61 67 65 20 61 74 20 74   percentage at t
6180: 68 65 20 72 69 67 68 74 20 73 68 6f 77 73 20 74  he right shows t
6190: 68 65 20 70 61 79 6c 6f 61 64 0a 20 20 20 20 64  he payload.    d
61a0: 69 76 69 64 65 64 20 62 79 20 74 68 65 20 74 6f  ivided by the to
61b0: 74 61 6c 20 66 69 6c 65 20 73 69 7a 65 2e 0a 0a  tal file size...
61c0: 50 65 72 63 65 6e 74 61 67 65 20 6f 66 20 74 6f  Percentage of to
61d0: 74 61 6c 20 64 61 74 61 62 61 73 65 0a 0a 20 20  tal database..  
61e0: 20 20 54 68 65 20 61 6d 6f 75 6e 74 20 6f 66 20    The amount of 
61f0: 74 68 65 20 63 6f 6d 70 6c 65 74 65 20 64 61 74  the complete dat
6200: 61 62 61 73 65 20 66 69 6c 65 20 74 68 61 74 20  abase file that 
6210: 69 73 20 64 65 76 6f 74 65 64 20 74 6f 20 73 74  is devoted to st
6220: 6f 72 69 6e 67 0a 20 20 20 20 69 6e 66 6f 72 6d  oring.    inform
6230: 61 74 69 6f 6e 20 64 65 73 63 72 69 62 65 64 20  ation described 
6240: 62 79 20 74 68 69 73 20 63 61 74 65 67 6f 72 79  by this category
6250: 2e 0a 0a 4e 75 6d 62 65 72 20 6f 66 20 65 6e 74  ...Number of ent
6260: 72 69 65 73 0a 0a 20 20 20 20 54 68 65 20 74 6f  ries..    The to
6270: 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 42 2d  tal number of B-
6280: 54 72 65 65 20 6b 65 79 2f 76 61 6c 75 65 20 70  Tree key/value p
6290: 61 69 72 73 20 73 74 6f 72 65 64 20 75 6e 64 65  airs stored unde
62a0: 72 20 74 68 69 73 20 63 61 74 65 67 6f 72 79 2e  r this category.
62b0: 0a 0a 42 79 74 65 73 20 6f 66 20 73 74 6f 72 61  ..Bytes of stora
62c0: 67 65 20 63 6f 6e 73 75 6d 65 64 0a 0a 20 20 20  ge consumed..   
62d0: 20 54 68 65 20 74 6f 74 61 6c 20 61 6d 6f 75 6e   The total amoun
62e0: 74 20 6f 66 20 64 69 73 6b 20 73 70 61 63 65 20  t of disk space 
62f0: 72 65 71 75 69 72 65 64 20 74 6f 20 73 74 6f 72  required to stor
6300: 65 20 61 6c 6c 20 42 2d 54 72 65 65 20 65 6e 74  e all B-Tree ent
6310: 72 69 65 73 0a 20 20 20 20 75 6e 64 65 72 20 74  ries.    under t
6320: 68 69 73 20 63 61 74 65 67 6f 72 79 2e 20 20 54  his category.  T
6330: 68 65 20 69 73 20 74 68 65 20 74 6f 74 61 6c 20  he is the total 
6340: 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  number of pages 
6350: 75 73 65 64 20 74 69 6d 65 73 0a 20 20 20 20 74  used times.    t
6360: 68 65 20 70 61 67 65 73 20 73 69 7a 65 2e 0a 0a  he pages size...
6370: 42 79 74 65 73 20 6f 66 20 70 61 79 6c 6f 61 64  Bytes of payload
6380: 0a 0a 20 20 20 20 54 68 65 20 61 6d 6f 75 6e 74  ..    The amount
6390: 20 6f 66 20 70 61 79 6c 6f 61 64 20 73 74 6f 72   of payload stor
63a0: 65 64 20 75 6e 64 65 72 20 74 68 69 73 20 63 61  ed under this ca
63b0: 74 65 67 6f 72 79 2e 20 20 50 61 79 6c 6f 61 64  tegory.  Payload
63c0: 20 69 73 20 74 68 65 20 64 61 74 61 0a 20 20 20   is the data.   
63d0: 20 70 61 72 74 20 6f 66 20 74 61 62 6c 65 20 65   part of table e
63e0: 6e 74 72 69 65 73 20 61 6e 64 20 74 68 65 20 6b  ntries and the k
63f0: 65 79 20 70 61 72 74 20 6f 66 20 69 6e 64 65 78  ey part of index
6400: 20 65 6e 74 72 69 65 73 2e 20 20 54 68 65 20 70   entries.  The p
6410: 65 72 63 65 6e 74 61 67 65 0a 20 20 20 20 61 74  ercentage.    at
6420: 20 74 68 65 20 72 69 67 68 74 20 69 73 20 74 68   the right is th
6430: 65 20 62 79 74 65 73 20 6f 66 20 70 61 79 6c 6f  e bytes of paylo
6440: 61 64 20 64 69 76 69 64 65 64 20 62 79 20 74 68  ad divided by th
6450: 65 20 62 79 74 65 73 20 6f 66 20 73 74 6f 72 61  e bytes of stora
6460: 67 65 20 0a 20 20 20 20 63 6f 6e 73 75 6d 65 64  ge .    consumed
6470: 2e 0a 0a 41 76 65 72 61 67 65 20 70 61 79 6c 6f  ...Average paylo
6480: 61 64 20 70 65 72 20 65 6e 74 72 79 0a 0a 20 20  ad per entry..  
6490: 20 20 54 68 65 20 61 76 65 72 61 67 65 20 61 6d    The average am
64a0: 6f 75 6e 74 20 6f 66 20 70 61 79 6c 6f 61 64 20  ount of payload 
64b0: 6f 6e 20 65 61 63 68 20 65 6e 74 72 79 2e 20 20  on each entry.  
64c0: 54 68 69 73 20 69 73 20 6a 75 73 74 20 74 68 65  This is just the
64d0: 20 62 79 74 65 73 20 6f 66 0a 20 20 20 20 70 61   bytes of.    pa
64e0: 79 6c 6f 61 64 20 64 69 76 69 64 65 64 20 62 79  yload divided by
64f0: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 65   the number of e
6500: 6e 74 72 69 65 73 2e 0a 0a 41 76 65 72 61 67 65  ntries...Average
6510: 20 75 6e 75 73 65 64 20 62 79 74 65 73 20 70 65   unused bytes pe
6520: 72 20 65 6e 74 72 79 0a 0a 20 20 20 20 54 68 65  r entry..    The
6530: 20 61 76 65 72 61 67 65 20 61 6d 6f 75 6e 74 20   average amount 
6540: 6f 66 20 66 72 65 65 20 73 70 61 63 65 20 72 65  of free space re
6550: 6d 61 69 6e 69 6e 67 20 6f 6e 20 61 6c 6c 20 70  maining on all p
6560: 61 67 65 73 20 75 6e 64 65 72 20 74 68 69 73 0a  ages under this.
6570: 20 20 20 20 63 61 74 65 67 6f 72 79 20 6f 6e 20      category on 
6580: 61 20 70 65 72 2d 65 6e 74 72 79 20 62 61 73 69  a per-entry basi
6590: 73 2e 20 20 54 68 69 73 20 69 73 20 74 68 65 20  s.  This is the 
65a0: 6e 75 6d 62 65 72 20 6f 66 20 75 6e 75 73 65 64  number of unused
65b0: 20 62 79 74 65 73 20 6f 6e 0a 20 20 20 20 61 6c   bytes on.    al
65c0: 6c 20 70 61 67 65 73 20 64 69 76 69 64 65 64 20  l pages divided 
65d0: 62 79 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  by the number of
65e0: 20 65 6e 74 72 69 65 73 2e 0a 0a 4e 6f 6e 2d 73   entries...Non-s
65f0: 65 71 75 65 6e 74 69 61 6c 20 70 61 67 65 73 0a  equential pages.
6600: 0a 20 20 20 20 54 68 65 20 6e 75 6d 62 65 72 20  .    The number 
6610: 6f 66 20 70 61 67 65 73 20 69 6e 20 74 68 65 20  of pages in the 
6620: 74 61 62 6c 65 20 6f 72 20 69 6e 64 65 78 20 74  table or index t
6630: 68 61 74 20 61 72 65 20 6f 75 74 20 6f 66 20 73  hat are out of s
6640: 65 71 75 65 6e 63 65 2e 0a 20 20 20 20 4d 61 6e  equence..    Man
6650: 79 20 66 69 6c 65 73 79 73 74 65 6d 73 20 61 72  y filesystems ar
6660: 65 20 6f 70 74 69 6d 69 7a 65 64 20 66 6f 72 20  e optimized for 
6670: 73 65 71 75 65 6e 74 69 61 6c 20 66 69 6c 65 20  sequential file 
6680: 61 63 63 65 73 73 20 73 6f 20 61 20 73 6d 61 6c  access so a smal
6690: 6c 0a 20 20 20 20 6e 75 6d 62 65 72 20 6f 66 20  l.    number of 
66a0: 6e 6f 6e 2d 73 65 71 75 65 6e 74 69 61 6c 20 70  non-sequential p
66b0: 61 67 65 73 20 6d 69 67 68 74 20 72 65 73 75 6c  ages might resul
66c0: 74 20 69 6e 20 66 61 73 74 65 72 20 71 75 65 72  t in faster quer
66d0: 69 65 73 2c 0a 20 20 20 20 65 73 70 65 63 69 61  ies,.    especia
66e0: 6c 6c 79 20 66 6f 72 20 6c 61 72 67 65 72 20 64  lly for larger d
66f0: 61 74 61 62 61 73 65 20 66 69 6c 65 73 20 74 68  atabase files th
6700: 61 74 20 64 6f 20 6e 6f 74 20 66 69 74 20 69 6e  at do not fit in
6710: 20 74 68 65 20 64 69 73 6b 20 63 61 63 68 65 2e   the disk cache.
6720: 0a 20 20 20 20 4e 6f 74 65 20 74 68 61 74 20 61  .    Note that a
6730: 66 74 65 72 20 72 75 6e 6e 69 6e 67 20 56 41 43  fter running VAC
6740: 55 55 4d 2c 20 74 68 65 20 72 6f 6f 74 20 70 61  UUM, the root pa
6750: 67 65 20 6f 66 20 65 61 63 68 20 74 61 62 6c 65  ge of each table
6760: 20 6f 72 20 69 6e 64 65 78 20 69 73 0a 20 20 20   or index is.   
6770: 20 61 74 20 74 68 65 20 62 65 67 69 6e 6e 69 6e   at the beginnin
6780: 67 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73  g of the databas
6790: 65 20 66 69 6c 65 20 61 6e 64 20 61 6c 6c 20 6f  e file and all o
67a0: 74 68 65 72 20 70 61 67 65 73 20 61 72 65 20 69  ther pages are i
67b0: 6e 20 61 0a 20 20 20 20 73 65 70 61 72 61 74 65  n a.    separate
67c0: 20 70 61 72 74 20 6f 66 20 74 68 65 20 64 61 74   part of the dat
67d0: 61 62 61 73 65 20 66 69 6c 65 2c 20 72 65 73 75  abase file, resu
67e0: 6c 74 69 6e 67 20 69 6e 20 61 20 73 69 6e 67 6c  lting in a singl
67f0: 65 20 6e 6f 6e 2d 0a 20 20 20 20 73 65 71 75 65  e non-.    seque
6800: 6e 74 69 61 6c 20 70 61 67 65 2e 0a 0a 4d 61 78  ntial page...Max
6810: 69 6d 75 6d 20 70 61 79 6c 6f 61 64 20 70 65 72  imum payload per
6820: 20 65 6e 74 72 79 0a 0a 20 20 20 20 54 68 65 20   entry..    The 
6830: 6c 61 72 67 65 73 74 20 70 61 79 6c 6f 61 64 20  largest payload 
6840: 73 69 7a 65 20 6f 66 20 61 6e 79 20 65 6e 74 72  size of any entr
6850: 79 2e 0a 0a 45 6e 74 72 69 65 73 20 74 68 61 74  y...Entries that
6860: 20 75 73 65 20 6f 76 65 72 66 6c 6f 77 0a 0a 20   use overflow.. 
6870: 20 20 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66     The number of
6880: 20 65 6e 74 72 69 65 73 20 74 68 61 74 20 75 73   entries that us
6890: 65 72 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 6f  er one or more o
68a0: 76 65 72 66 6c 6f 77 20 70 61 67 65 73 2e 0a 0a  verflow pages...
68b0: 54 6f 74 61 6c 20 70 61 67 65 73 20 75 73 65 64  Total pages used
68c0: 0a 0a 20 20 20 20 54 68 69 73 20 69 73 20 74 68  ..    This is th
68d0: 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65  e number of page
68e0: 73 20 75 73 65 64 20 74 6f 20 68 6f 6c 64 20 61  s used to hold a
68f0: 6c 6c 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 69  ll information i
6900: 6e 20 74 68 65 20 63 75 72 72 65 6e 74 0a 20 20  n the current.  
6910: 20 20 63 61 74 65 67 6f 72 79 2e 20 20 54 68 69    category.  Thi
6920: 73 20 69 73 20 74 68 65 20 73 75 6d 20 6f 66 20  s is the sum of 
6930: 69 6e 64 65 78 2c 20 70 72 69 6d 61 72 79 2c 20  index, primary, 
6940: 61 6e 64 20 6f 76 65 72 66 6c 6f 77 20 70 61 67  and overflow pag
6950: 65 73 2e 0a 0a 49 6e 64 65 78 20 70 61 67 65 73  es...Index pages
6960: 20 75 73 65 64 0a 0a 20 20 20 20 54 68 69 73 20   used..    This 
6970: 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  is the number of
6980: 20 70 61 67 65 73 20 69 6e 20 61 20 74 61 62 6c   pages in a tabl
6990: 65 20 42 2d 74 72 65 65 20 74 68 61 74 20 68 6f  e B-tree that ho
69a0: 6c 64 20 6f 6e 6c 79 20 6b 65 79 20 28 72 6f 77  ld only key (row
69b0: 69 64 29 0a 20 20 20 20 69 6e 66 6f 72 6d 61 74  id).    informat
69c0: 69 6f 6e 20 61 6e 64 20 6e 6f 20 64 61 74 61 2e  ion and no data.
69d0: 0a 0a 50 72 69 6d 61 72 79 20 70 61 67 65 73 20  ..Primary pages 
69e0: 75 73 65 64 0a 0a 20 20 20 20 54 68 69 73 20 69  used..    This i
69f0: 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  s the number of 
6a00: 42 2d 74 72 65 65 20 70 61 67 65 73 20 74 68 61  B-tree pages tha
6a10: 74 20 68 6f 6c 64 20 62 6f 74 68 20 6b 65 79 20  t hold both key 
6a20: 61 6e 64 20 64 61 74 61 2e 0a 0a 4f 76 65 72 66  and data...Overf
6a30: 6c 6f 77 20 70 61 67 65 73 20 75 73 65 64 0a 0a  low pages used..
6a40: 20 20 20 20 54 68 65 20 74 6f 74 61 6c 20 6e 75      The total nu
6a50: 6d 62 65 72 20 6f 66 20 6f 76 65 72 66 6c 6f 77  mber of overflow
6a60: 20 70 61 67 65 73 20 75 73 65 64 20 66 6f 72 20   pages used for 
6a70: 74 68 69 73 20 63 61 74 65 67 6f 72 79 2e 0a 0a  this category...
6a80: 55 6e 75 73 65 64 20 62 79 74 65 73 20 6f 6e 20  Unused bytes on 
6a90: 69 6e 64 65 78 20 70 61 67 65 73 0a 0a 20 20 20  index pages..   
6aa0: 20 54 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65   The total numbe
6ab0: 72 20 6f 66 20 62 79 74 65 73 20 6f 66 20 75 6e  r of bytes of un
6ac0: 75 73 65 64 20 73 70 61 63 65 20 6f 6e 20 61 6c  used space on al
6ad0: 6c 20 69 6e 64 65 78 20 70 61 67 65 73 2e 20 20  l index pages.  
6ae0: 54 68 65 0a 20 20 20 20 70 65 72 63 65 6e 74 61  The.    percenta
6af0: 67 65 20 61 74 20 74 68 65 20 72 69 67 68 74 20  ge at the right 
6b00: 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  is the number of
6b10: 20 75 6e 75 73 65 64 20 62 79 74 65 73 20 64 69   unused bytes di
6b20: 76 69 64 65 64 20 62 79 20 74 68 65 0a 20 20 20  vided by the.   
6b30: 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66   total number of
6b40: 20 62 79 74 65 73 20 6f 6e 20 69 6e 64 65 78 20   bytes on index 
6b50: 70 61 67 65 73 2e 0a 0a 55 6e 75 73 65 64 20 62  pages...Unused b
6b60: 79 74 65 73 20 6f 6e 20 70 72 69 6d 61 72 79 20  ytes on primary 
6b70: 70 61 67 65 73 0a 0a 20 20 20 20 54 68 65 20 74  pages..    The t
6b80: 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 62  otal number of b
6b90: 79 74 65 73 20 6f 66 20 75 6e 75 73 65 64 20 73  ytes of unused s
6ba0: 70 61 63 65 20 6f 6e 20 61 6c 6c 20 70 72 69 6d  pace on all prim
6bb0: 61 72 79 20 70 61 67 65 73 2e 20 20 54 68 65 0a  ary pages.  The.
6bc0: 20 20 20 20 70 65 72 63 65 6e 74 61 67 65 20 61      percentage a
6bd0: 74 20 74 68 65 20 72 69 67 68 74 20 69 73 20 74  t the right is t
6be0: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 75 6e 75  he number of unu
6bf0: 73 65 64 20 62 79 74 65 73 20 64 69 76 69 64 65  sed bytes divide
6c00: 64 20 62 79 20 74 68 65 0a 20 20 20 20 74 6f 74  d by the.    tot
6c10: 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74  al number of byt
6c20: 65 73 20 6f 6e 20 70 72 69 6d 61 72 79 20 70 61  es on primary pa
6c30: 67 65 73 2e 0a 0a 55 6e 75 73 65 64 20 62 79 74  ges...Unused byt
6c40: 65 73 20 6f 6e 20 6f 76 65 72 66 6c 6f 77 20 70  es on overflow p
6c50: 61 67 65 73 0a 0a 20 20 20 20 54 68 65 20 74 6f  ages..    The to
6c60: 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 62 79  tal number of by
6c70: 74 65 73 20 6f 66 20 75 6e 75 73 65 64 20 73 70  tes of unused sp
6c80: 61 63 65 20 6f 6e 20 61 6c 6c 20 6f 76 65 72 66  ace on all overf
6c90: 6c 6f 77 20 70 61 67 65 73 2e 20 20 54 68 65 0a  low pages.  The.
6ca0: 20 20 20 20 70 65 72 63 65 6e 74 61 67 65 20 61      percentage a
6cb0: 74 20 74 68 65 20 72 69 67 68 74 20 69 73 20 74  t the right is t
6cc0: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 75 6e 75  he number of unu
6cd0: 73 65 64 20 62 79 74 65 73 20 64 69 76 69 64 65  sed bytes divide
6ce0: 64 20 62 79 20 74 68 65 0a 20 20 20 20 74 6f 74  d by the.    tot
6cf0: 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74  al number of byt
6d00: 65 73 20 6f 6e 20 6f 76 65 72 66 6c 6f 77 20 70  es on overflow p
6d10: 61 67 65 73 2e 0a 0a 55 6e 75 73 65 64 20 62 79  ages...Unused by
6d20: 74 65 73 20 6f 6e 20 61 6c 6c 20 70 61 67 65 73  tes on all pages
6d30: 0a 0a 20 20 20 20 54 68 65 20 74 6f 74 61 6c 20  ..    The total 
6d40: 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  number of bytes 
6d50: 6f 66 20 75 6e 75 73 65 64 20 73 70 61 63 65 20  of unused space 
6d60: 6f 6e 20 61 6c 6c 20 70 72 69 6d 61 72 79 20 61  on all primary a
6d70: 6e 64 20 6f 76 65 72 66 6c 6f 77 20 0a 20 20 20  nd overflow .   
6d80: 20 70 61 67 65 73 2e 20 20 54 68 65 20 70 65 72   pages.  The per
6d90: 63 65 6e 74 61 67 65 20 61 74 20 74 68 65 20 72  centage at the r
6da0: 69 67 68 74 20 69 73 20 74 68 65 20 6e 75 6d 62  ight is the numb
6db0: 65 72 20 6f 66 20 75 6e 75 73 65 64 20 62 79 74  er of unused byt
6dc0: 65 73 20 0a 20 20 20 20 64 69 76 69 64 65 64 20  es .    divided 
6dd0: 62 79 20 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d  by the total num
6de0: 62 65 72 20 6f 66 20 62 79 74 65 73 2e 0a 7d 0a  ber of bytes..}.
6df0: 0a 23 20 4f 75 74 70 75 74 20 61 20 64 75 6d 70  .# Output a dump
6e00: 20 6f 66 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72   of the in-memor
6e10: 79 20 64 61 74 61 62 61 73 65 2e 20 54 68 69 73  y database. This
6e20: 20 63 61 6e 20 62 65 20 75 73 65 64 20 66 6f 72   can be used for
6e30: 20 6d 6f 72 65 0a 23 20 63 6f 6d 70 6c 65 78 20   more.# complex 
6e40: 6f 66 66 6c 69 6e 65 20 61 6e 61 6c 79 73 69 73  offline analysis
6e50: 2e 0a 23 0a 74 69 74 6c 65 6c 69 6e 65 20 7b 7d  ..#.titleline {}
6e60: 0a 70 75 74 73 20 22 54 68 65 20 65 6e 74 69 72  .puts "The entir
6e70: 65 20 74 65 78 74 20 6f 66 20 74 68 69 73 20 72  e text of this r
6e80: 65 70 6f 72 74 20 63 61 6e 20 62 65 20 73 6f 75  eport can be sou
6e90: 72 63 65 64 20 69 6e 74 6f 20 61 6e 79 20 53 51  rced into any SQ
6ea0: 4c 20 64 61 74 61 62 61 73 65 22 0a 70 75 74 73  L database".puts
6eb0: 20 22 65 6e 67 69 6e 65 20 66 6f 72 20 66 75 72   "engine for fur
6ec0: 74 68 65 72 20 61 6e 61 6c 79 73 69 73 2e 20 20  ther analysis.  
6ed0: 41 6c 6c 20 6f 66 20 74 68 65 20 74 65 78 74 20  All of the text 
6ee0: 61 62 6f 76 65 20 69 73 20 61 6e 20 53 51 4c 20  above is an SQL 
6ef0: 63 6f 6d 6d 65 6e 74 2e 22 0a 70 75 74 73 20 22  comment.".puts "
6f00: 54 68 65 20 64 61 74 61 20 75 73 65 64 20 74 6f  The data used to
6f10: 20 67 65 6e 65 72 61 74 65 20 74 68 69 73 20 72   generate this r
6f20: 65 70 6f 72 74 20 66 6f 6c 6c 6f 77 73 3a 22 0a  eport follows:".
6f30: 70 75 74 73 20 22 2a 2f 22 0a 70 75 74 73 20 22  puts "*/".puts "
6f40: 42 45 47 49 4e 3b 22 0a 70 75 74 73 20 24 74 61  BEGIN;".puts $ta
6f50: 62 6c 65 64 65 66 0a 75 6e 73 65 74 20 2d 6e 6f  bledef.unset -no
6f60: 63 6f 6d 70 6c 61 69 6e 20 78 0a 6d 65 6d 20 65  complain x.mem e
6f70: 76 61 6c 20 7b 53 45 4c 45 43 54 20 2a 20 46 52  val {SELECT * FR
6f80: 4f 4d 20 73 70 61 63 65 5f 75 73 65 64 7d 20 78  OM space_used} x
6f90: 20 7b 0a 20 20 70 75 74 73 20 2d 6e 6f 6e 65 77   {.  puts -nonew
6fa0: 6c 69 6e 65 20 22 49 4e 53 45 52 54 20 49 4e 54  line "INSERT INT
6fb0: 4f 20 73 70 61 63 65 5f 75 73 65 64 20 56 41 4c  O space_used VAL
6fc0: 55 45 53 22 0a 20 20 73 65 74 20 73 65 70 20 28  UES".  set sep (
6fd0: 0a 20 20 66 6f 72 65 61 63 68 20 63 6f 6c 20 24  .  foreach col $
6fe0: 78 28 2a 29 20 7b 0a 20 20 20 20 73 65 74 20 76  x(*) {.    set v
6ff0: 20 24 78 28 24 63 6f 6c 29 0a 20 20 20 20 69 66   $x($col).    if
7000: 20 7b 24 76 3d 3d 22 22 20 7c 7c 20 21 5b 73 74   {$v=="" || ![st
7010: 72 69 6e 67 20 69 73 20 64 6f 75 62 6c 65 20 24  ring is double $
7020: 76 5d 7d 20 7b 73 65 74 20 76 20 27 5b 71 75 6f  v]} {set v '[quo
7030: 74 65 20 24 76 5d 27 7d 0a 20 20 20 20 70 75 74  te $v]'}.    put
7040: 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 24 73 65  s -nonewline $se
7050: 70 24 76 0a 20 20 20 20 73 65 74 20 73 65 70 20  p$v.    set sep 
7060: 2c 0a 20 20 7d 0a 20 20 70 75 74 73 20 22 29 3b  ,.  }.  puts ");
7070: 22 0a 7d 0a 70 75 74 73 20 22 43 4f 4d 4d 49 54  ".}.puts "COMMIT
7080: 3b 22 0a 0a 7d 20 65 72 72 5d 7d 20 7b 0a 20 20  ;"..} err]} {.  
7090: 70 75 74 73 20 22 45 52 52 4f 52 3a 20 24 65 72  puts "ERROR: $er
70a0: 72 22 0a 20 20 70 75 74 73 20 24 65 72 72 6f 72  r".  puts $error
70b0: 49 6e 66 6f 0a 20 20 65 78 69 74 20 31 0a 7d 0a  Info.  exit 1.}.