/ Hex Artifact Content
Login

Artifact 5b47b70b9a0d216ec63a5b5547b3642dd308e53a:


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 23 20 47 65 74  unused..#..# Get
00c0: 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 65   the name of the
00d0: 20 64 61 74 61 62 61 73 65 20 74 6f 20 61 6e 61   database to ana
00e0: 6c 79 7a 65 0a 23 0a 23 73 65 74 20 61 72 67 76  lyze.#.#set argv
00f0: 20 24 61 72 67 76 30 0a 69 66 20 7b 5b 6c 6c 65   $argv0.if {[lle
0100: 6e 67 74 68 20 24 61 72 67 76 5d 21 3d 31 7d 20  ngth $argv]!=1} 
0110: 7b 0a 20 20 70 75 74 73 20 73 74 64 65 72 72 20  {.  puts stderr 
0120: 22 55 73 61 67 65 3a 20 24 61 72 67 76 30 20 64  "Usage: $argv0 d
0130: 61 74 61 62 61 73 65 2d 6e 61 6d 65 22 0a 20 20  atabase-name".  
0140: 65 78 69 74 20 31 0a 7d 0a 73 65 74 20 66 69 6c  exit 1.}.set fil
0150: 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 20 5b 6c 69  e_to_analyze [li
0160: 6e 64 65 78 20 24 61 72 67 76 20 30 5d 0a 69 66  ndex $argv 0].if
0170: 20 7b 21 5b 66 69 6c 65 20 65 78 69 73 74 73 20   {![file exists 
0180: 24 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65  $file_to_analyze
0190: 5d 7d 20 7b 0a 20 20 70 75 74 73 20 73 74 64 65  ]} {.  puts stde
01a0: 72 72 20 22 4e 6f 20 73 75 63 68 20 66 69 6c 65  rr "No such file
01b0: 3a 20 24 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79  : $file_to_analy
01c0: 7a 65 22 0a 20 20 65 78 69 74 20 31 0a 7d 0a 69  ze".  exit 1.}.i
01d0: 66 20 7b 21 5b 66 69 6c 65 20 72 65 61 64 61 62  f {![file readab
01e0: 6c 65 20 24 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c  le $file_to_anal
01f0: 79 7a 65 5d 7d 20 7b 0a 20 20 70 75 74 73 20 73  yze]} {.  puts s
0200: 74 64 65 72 72 20 22 46 69 6c 65 20 69 73 20 6e  tderr "File is n
0210: 6f 74 20 72 65 61 64 61 62 6c 65 3a 20 24 66 69  ot readable: $fi
0220: 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 22 0a 20  le_to_analyze". 
0230: 20 65 78 69 74 20 31 0a 7d 0a 69 66 20 7b 5b 66   exit 1.}.if {[f
0240: 69 6c 65 20 73 69 7a 65 20 24 66 69 6c 65 5f 74  ile size $file_t
0250: 6f 5f 61 6e 61 6c 79 7a 65 5d 3c 35 31 32 7d 20  o_analyze]<512} 
0260: 7b 0a 20 20 70 75 74 73 20 73 74 64 65 72 72 20  {.  puts stderr 
0270: 22 45 6d 70 74 79 20 6f 72 20 6d 61 6c 66 6f 72  "Empty or malfor
0280: 6d 65 64 20 64 61 74 61 62 61 73 65 3a 20 24 66  med database: $f
0290: 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 22 0a  ile_to_analyze".
02a0: 20 20 65 78 69 74 20 31 0a 7d 0a 0a 23 20 4f 70    exit 1.}..# Op
02b0: 65 6e 20 74 68 65 20 64 61 74 61 62 61 73 65 0a  en the database.
02c0: 23 0a 73 71 6c 69 74 65 33 20 64 62 20 5b 6c 69  #.sqlite3 db [li
02d0: 6e 64 65 78 20 24 61 72 67 76 20 30 5d 0a 73 65  ndex $argv 0].se
02e0: 74 20 44 42 20 5b 62 74 72 65 65 5f 6f 70 65 6e  t DB [btree_open
02f0: 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 76 20 30   [lindex $argv 0
0300: 5d 20 31 30 30 30 20 30 5d 0a 0a 23 20 49 6e 2d  ] 1000 0]..# In-
0310: 6d 65 6d 6f 72 79 20 64 61 74 61 62 61 73 65 20  memory database 
0320: 66 6f 72 20 63 6f 6c 6c 65 63 74 69 6e 67 20 73  for collecting s
0330: 74 61 74 69 73 74 69 63 73 2e 20 54 68 69 73 20  tatistics. This 
0340: 73 63 72 69 70 74 20 6c 6f 6f 70 73 20 74 68 72  script loops thr
0350: 6f 75 67 68 0a 23 20 74 68 65 20 74 61 62 6c 65  ough.# the table
0360: 73 20 61 6e 64 20 69 6e 64 69 63 65 73 20 69 6e  s and indices in
0370: 20 74 68 65 20 64 61 74 61 62 61 73 65 20 62 65   the database be
0380: 69 6e 67 20 61 6e 61 6c 79 7a 65 64 2c 20 61 64  ing analyzed, ad
0390: 64 69 6e 67 20 61 20 72 6f 77 20 66 6f 72 20 65  ding a row for e
03a0: 61 63 68 0a 23 20 74 6f 20 61 6e 20 69 6e 2d 6d  ach.# to an in-m
03b0: 65 6d 6f 72 79 20 64 61 74 61 62 61 73 65 20 28  emory database (
03c0: 66 6f 72 20 77 68 69 63 68 20 74 68 65 20 73 63  for which the sc
03d0: 68 65 6d 61 20 69 73 20 73 68 6f 77 6e 20 62 65  hema is shown be
03e0: 6c 6f 77 29 2e 20 49 74 20 74 68 65 6e 0a 23 20  low). It then.# 
03f0: 71 75 65 72 69 65 73 20 74 68 65 20 69 6e 2d 6d  queries the in-m
0400: 65 6d 6f 72 79 20 64 62 20 74 6f 20 70 72 6f 64  emory db to prod
0410: 75 63 65 20 74 68 65 20 73 70 61 63 65 2d 61 6e  uce the space-an
0420: 61 6c 79 73 69 73 20 72 65 70 6f 72 74 2e 0a 23  alysis report..#
0430: 0a 73 71 6c 69 74 65 33 20 6d 65 6d 20 3a 6d 65  .sqlite3 mem :me
0440: 6d 6f 72 79 3a 0a 73 65 74 20 74 61 62 6c 65 64  mory:.set tabled
0450: 65 66 5c 0a 7b 43 52 45 41 54 45 20 54 41 42 4c  ef\.{CREATE TABL
0460: 45 20 73 70 61 63 65 5f 75 73 65 64 28 0a 20 20  E space_used(.  
0470: 20 6e 61 6d 65 20 63 6c 6f 62 2c 20 20 20 20 20   name clob,     
0480: 20 20 20 2d 2d 20 4e 61 6d 65 20 6f 66 20 61 20     -- Name of a 
0490: 74 61 62 6c 65 20 6f 72 20 69 6e 64 65 78 20 69  table or index i
04a0: 6e 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66  n the database f
04b0: 69 6c 65 0a 20 20 20 74 62 6c 6e 61 6d 65 20 63  ile.   tblname c
04c0: 6c 6f 62 2c 20 20 20 20 20 2d 2d 20 4e 61 6d 65  lob,     -- Name
04d0: 20 6f 66 20 61 73 73 6f 63 69 61 74 65 64 20 74   of associated t
04e0: 61 62 6c 65 0a 20 20 20 69 73 5f 69 6e 64 65 78  able.   is_index
04f0: 20 62 6f 6f 6c 65 61 6e 2c 20 2d 2d 20 54 52 55   boolean, -- TRU
0500: 45 20 69 66 20 69 74 20 69 73 20 61 6e 20 69 6e  E if it is an in
0510: 64 65 78 2c 20 66 61 6c 73 65 20 66 6f 72 20 61  dex, false for a
0520: 20 74 61 62 6c 65 0a 20 20 20 6e 65 6e 74 72 79   table.   nentry
0530: 20 69 6e 74 2c 20 20 20 20 20 20 20 2d 2d 20 4e   int,       -- N
0540: 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73  umber of entries
0550: 20 69 6e 20 74 68 65 20 42 54 72 65 65 0a 20 20   in the BTree.  
0560: 20 6c 65 61 66 5f 65 6e 74 72 69 65 73 20 69 6e   leaf_entries in
0570: 74 2c 20 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20  t, -- Number of 
0580: 6c 65 61 66 20 65 6e 74 72 69 65 73 0a 20 20 20  leaf entries.   
0590: 70 61 79 6c 6f 61 64 20 69 6e 74 2c 20 20 20 20  payload int,    
05a0: 20 20 2d 2d 20 54 6f 74 61 6c 20 61 6d 6f 75 6e    -- Total amoun
05b0: 74 20 6f 66 20 64 61 74 61 20 73 74 6f 72 65 64  t of data stored
05c0: 20 69 6e 20 74 68 69 73 20 74 61 62 6c 65 20 6f   in this table o
05d0: 72 20 69 6e 64 65 78 0a 20 20 20 6f 76 66 6c 5f  r index.   ovfl_
05e0: 70 61 79 6c 6f 61 64 20 69 6e 74 2c 20 2d 2d 20  payload int, -- 
05f0: 54 6f 74 61 6c 20 61 6d 6f 75 6e 74 20 6f 66 20  Total amount of 
0600: 64 61 74 61 20 73 74 6f 72 65 64 20 6f 6e 20 6f  data stored on o
0610: 76 65 72 66 6c 6f 77 20 70 61 67 65 73 0a 20 20  verflow pages.  
0620: 20 6f 76 66 6c 5f 63 6e 74 20 69 6e 74 2c 20 20   ovfl_cnt int,  
0630: 20 20 20 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20     -- Number of 
0640: 65 6e 74 72 69 65 73 20 74 68 61 74 20 75 73 65  entries that use
0650: 20 6f 76 65 72 66 6c 6f 77 0a 20 20 20 6d 78 5f   overflow.   mx_
0660: 70 61 79 6c 6f 61 64 20 69 6e 74 2c 20 20 20 2d  payload int,   -
0670: 2d 20 4d 61 78 69 6d 75 6d 20 70 61 79 6c 6f 61  - Maximum payloa
0680: 64 20 73 69 7a 65 0a 20 20 20 69 6e 74 5f 70 61  d size.   int_pa
0690: 67 65 73 20 69 6e 74 2c 20 20 20 20 2d 2d 20 4e  ges int,    -- N
06a0: 75 6d 62 65 72 20 6f 66 20 69 6e 74 65 72 69 6f  umber of interio
06b0: 72 20 70 61 67 65 73 20 75 73 65 64 0a 20 20 20  r pages used.   
06c0: 6c 65 61 66 5f 70 61 67 65 73 20 69 6e 74 2c 20  leaf_pages int, 
06d0: 20 20 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20 6c    -- Number of l
06e0: 65 61 66 20 70 61 67 65 73 20 75 73 65 64 0a 20  eaf pages used. 
06f0: 20 20 6f 76 66 6c 5f 70 61 67 65 73 20 69 6e 74    ovfl_pages int
0700: 2c 20 20 20 2d 2d 20 4e 75 6d 62 65 72 20 6f 66  ,   -- Number of
0710: 20 6f 76 65 72 66 6c 6f 77 20 70 61 67 65 73 20   overflow pages 
0720: 75 73 65 64 0a 20 20 20 69 6e 74 5f 75 6e 75 73  used.   int_unus
0730: 65 64 20 69 6e 74 2c 20 20 20 2d 2d 20 4e 75 6d  ed int,   -- Num
0740: 62 65 72 20 6f 66 20 75 6e 75 73 65 64 20 62 79  ber of unused by
0750: 74 65 73 20 6f 6e 20 69 6e 74 65 72 69 6f 72 20  tes on interior 
0760: 70 61 67 65 73 0a 20 20 20 6c 65 61 66 5f 75 6e  pages.   leaf_un
0770: 75 73 65 64 20 69 6e 74 2c 20 20 2d 2d 20 4e 75  used int,  -- Nu
0780: 6d 62 65 72 20 6f 66 20 75 6e 75 73 65 64 20 62  mber of unused b
0790: 79 74 65 73 20 6f 6e 20 70 72 69 6d 61 72 79 20  ytes on primary 
07a0: 70 61 67 65 73 0a 20 20 20 6f 76 66 6c 5f 75 6e  pages.   ovfl_un
07b0: 75 73 65 64 20 69 6e 74 20 20 20 2d 2d 20 4e 75  used int   -- Nu
07c0: 6d 62 65 72 20 6f 66 20 75 6e 75 73 65 64 20 62  mber of unused b
07d0: 79 74 65 73 20 6f 6e 20 6f 76 65 72 66 6c 6f 77  ytes on overflow
07e0: 20 70 61 67 65 73 0a 29 3b 7d 0a 6d 65 6d 20 65   pages.);}.mem e
07f0: 76 61 6c 20 24 74 61 62 6c 65 64 65 66 0a 0a 70  val $tabledef..p
0800: 72 6f 63 20 69 6e 74 65 67 65 72 69 66 79 20 7b  roc integerify {
0810: 72 65 61 6c 7d 20 7b 0a 20 20 72 65 74 75 72 6e  real} {.  return
0820: 20 5b 65 78 70 72 20 69 6e 74 28 24 72 65 61 6c   [expr int($real
0830: 29 5d 0a 7d 0a 6d 65 6d 20 66 75 6e 63 74 69 6f  )].}.mem functio
0840: 6e 20 69 6e 74 20 69 6e 74 65 67 65 72 69 66 79  n int integerify
0850: 0a 0a 23 20 51 75 6f 74 65 20 61 20 73 74 72 69  ..# Quote a stri
0860: 6e 67 20 66 6f 72 20 75 73 65 20 69 6e 20 61 6e  ng for use in an
0870: 20 53 51 4c 20 71 75 65 72 79 2e 20 45 78 61 6d   SQL query. Exam
0880: 70 6c 65 73 3a 0a 23 0a 23 20 5b 71 75 6f 74 65  ples:.#.# [quote
0890: 20 7b 68 65 6c 6c 6f 20 77 6f 72 6c 64 7d 5d 20   {hello world}] 
08a0: 20 20 3d 3d 20 7b 27 68 65 6c 6c 6f 20 77 6f 72    == {'hello wor
08b0: 6c 64 27 7d 0a 23 20 5b 71 75 6f 74 65 20 7b 68  ld'}.# [quote {h
08c0: 65 6c 6c 6f 20 77 6f 72 6c 64 27 73 7d 5d 20 3d  ello world's}] =
08d0: 3d 20 7b 27 68 65 6c 6c 6f 20 77 6f 72 6c 64 27  = {'hello world'
08e0: 27 73 27 7d 0a 23 0a 70 72 6f 63 20 71 75 6f 74  's'}.#.proc quot
08f0: 65 20 7b 74 78 74 7d 20 7b 0a 20 20 72 65 67 73  e {txt} {.  regs
0900: 75 62 20 2d 61 6c 6c 20 27 20 24 74 78 74 20 27  ub -all ' $txt '
0910: 27 20 71 0a 20 20 72 65 74 75 72 6e 20 27 24 71  ' q.  return '$q
0920: 27 0a 7d 0a 0a 23 20 54 68 69 73 20 70 72 6f 63  '.}..# This proc
0930: 20 69 73 20 61 20 77 72 61 70 70 65 72 20 61 72   is a wrapper ar
0940: 6f 75 6e 64 20 74 68 65 20 62 74 72 65 65 5f 63  ound the btree_c
0950: 75 72 73 6f 72 5f 69 6e 66 6f 20 63 6f 6d 6d 61  ursor_info comma
0960: 6e 64 2e 20 54 68 65 0a 23 20 73 65 63 6f 6e 64  nd. The.# second
0970: 20 61 72 67 75 6d 65 6e 74 20 69 73 20 61 6e 20   argument is an 
0980: 6f 70 65 6e 20 62 74 72 65 65 20 63 75 72 73 6f  open btree curso
0990: 72 20 72 65 74 75 72 6e 65 64 20 62 79 20 5b 62  r returned by [b
09a0: 74 72 65 65 5f 63 75 72 73 6f 72 5d 2e 0a 23 20  tree_cursor]..# 
09b0: 54 68 65 20 66 69 72 73 74 20 61 72 67 75 6d 65  The first argume
09c0: 6e 74 20 69 73 20 74 68 65 20 6e 61 6d 65 20 6f  nt is the name o
09d0: 66 20 61 6e 20 61 72 72 61 79 20 76 61 72 69 61  f an array varia
09e0: 62 6c 65 20 74 68 61 74 20 65 78 69 73 74 73 20  ble that exists 
09f0: 69 6e 0a 23 20 74 68 65 20 73 63 6f 70 65 20 6f  in.# the scope o
0a00: 66 20 74 68 65 20 63 61 6c 6c 65 72 2e 20 49 66  f the caller. If
0a10: 20 74 68 65 20 74 68 69 72 64 20 61 72 67 75 6d   the third argum
0a20: 65 6e 74 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2c  ent is non-zero,
0a30: 20 74 68 65 6e 0a 23 20 69 6e 66 6f 20 69 73 20   then.# info is 
0a40: 72 65 74 75 72 6e 65 64 20 66 6f 72 20 74 68 65  returned for the
0a50: 20 70 61 67 65 20 74 68 61 74 20 6c 69 65 73 20   page that lies 
0a60: 24 75 70 20 65 6e 74 72 69 65 73 20 75 70 77 61  $up entries upwa
0a70: 72 64 73 20 69 6e 20 74 68 65 0a 23 20 74 72 65  rds in the.# tre
0a80: 65 2d 73 74 72 75 63 74 75 72 65 2e 20 28 69 2e  e-structure. (i.
0a90: 65 2e 20 24 75 70 3d 3d 31 20 72 65 74 75 72 6e  e. $up==1 return
0aa0: 73 20 74 68 65 20 70 61 72 65 6e 74 20 70 61 67  s the parent pag
0ab0: 65 2c 20 24 75 70 3d 3d 32 20 74 68 65 20 0a 23  e, $up==2 the .#
0ac0: 20 67 72 61 6e 64 70 61 72 65 6e 74 20 65 74 63   grandparent etc
0ad0: 2e 29 0a 23 0a 23 20 54 68 65 20 66 6f 6c 6c 6f  .).#.# The follo
0ae0: 77 69 6e 67 20 65 6e 74 72 69 65 73 20 69 6e 20  wing entries in 
0af0: 74 68 61 74 20 61 72 72 61 79 20 61 72 65 20 66  that array are f
0b00: 69 6c 6c 65 64 20 69 6e 20 77 69 74 68 20 69 6e  illed in with in
0b10: 66 6f 72 6d 61 74 69 6f 6e 20 72 65 74 72 69 65  formation retrie
0b20: 76 65 64 0a 23 20 75 73 69 6e 67 20 5b 62 74 72  ved.# using [btr
0b30: 65 65 5f 63 75 72 73 6f 72 5f 69 6e 66 6f 5d 3a  ee_cursor_info]:
0b40: 0a 23 0a 23 20 20 20 24 61 72 72 61 79 76 61 72  .#.#   $arrayvar
0b50: 28 70 61 67 65 5f 6e 6f 29 20 20 20 20 20 20 20  (page_no)       
0b60: 20 20 20 20 20 20 3d 20 20 54 68 65 20 70 61 67        =  The pag
0b70: 65 20 6e 75 6d 62 65 72 0a 23 20 20 20 24 61 72  e number.#   $ar
0b80: 72 61 79 76 61 72 28 65 6e 74 72 79 5f 6e 6f 29  rayvar(entry_no)
0b90: 20 20 20 20 20 20 20 20 20 20 20 20 3d 20 20 54              =  T
0ba0: 68 65 20 65 6e 74 72 79 20 6e 75 6d 62 65 72 0a  he entry number.
0bb0: 23 20 20 20 24 61 72 72 61 79 76 61 72 28 70 61  #   $arrayvar(pa
0bc0: 67 65 5f 65 6e 74 72 69 65 73 29 20 20 20 20 20  ge_entries)     
0bd0: 20 20 20 3d 20 20 54 6f 74 61 6c 20 6e 75 6d 62     =  Total numb
0be0: 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20 6f 6e  er of entries on
0bf0: 20 74 68 69 73 20 70 61 67 65 0a 23 20 20 20 24   this page.#   $
0c00: 61 72 72 61 79 76 61 72 28 63 65 6c 6c 5f 73 69  arrayvar(cell_si
0c10: 7a 65 29 20 20 20 20 20 20 20 20 20 20 20 3d 20  ze)           = 
0c20: 20 43 65 6c 6c 20 73 69 7a 65 20 28 6c 6f 63 61   Cell size (loca
0c30: 6c 20 70 61 79 6c 6f 61 64 20 2b 20 68 65 61 64  l payload + head
0c40: 65 72 29 0a 23 20 20 20 24 61 72 72 61 79 76 61  er).#   $arrayva
0c50: 72 28 70 61 67 65 5f 66 72 65 65 62 79 74 65 73  r(page_freebytes
0c60: 29 20 20 20 20 20 20 3d 20 20 4e 75 6d 62 65 72  )      =  Number
0c70: 20 6f 66 20 66 72 65 65 20 62 79 74 65 73 20 6f   of free bytes o
0c80: 6e 20 74 68 69 73 20 70 61 67 65 0a 23 20 20 20  n this page.#   
0c90: 24 61 72 72 61 79 76 61 72 28 70 61 67 65 5f 66  $arrayvar(page_f
0ca0: 72 65 65 62 6c 6f 63 6b 73 29 20 20 20 20 20 3d  reeblocks)     =
0cb0: 20 20 4e 75 6d 62 65 72 20 6f 66 20 66 72 65 65    Number of free
0cc0: 20 62 6c 6f 63 6b 73 20 6f 6e 20 74 68 65 20 70   blocks on the p
0cd0: 61 67 65 0a 23 20 20 20 24 61 72 72 61 79 76 61  age.#   $arrayva
0ce0: 72 28 70 61 79 6c 6f 61 64 5f 62 79 74 65 73 29  r(payload_bytes)
0cf0: 20 20 20 20 20 20 20 3d 20 20 54 6f 74 61 6c 20         =  Total 
0d00: 70 61 79 6c 6f 61 64 20 73 69 7a 65 20 28 6c 6f  payload size (lo
0d10: 63 61 6c 20 2b 20 6f 76 65 72 66 6c 6f 77 29 0a  cal + overflow).
0d20: 23 20 20 20 24 61 72 72 61 79 76 61 72 28 68 65  #   $arrayvar(he
0d30: 61 64 65 72 5f 62 79 74 65 73 29 20 20 20 20 20  ader_bytes)     
0d40: 20 20 20 3d 20 20 48 65 61 64 65 72 20 73 69 7a     =  Header siz
0d50: 65 20 69 6e 20 62 79 74 65 73 0a 23 20 20 20 24  e in bytes.#   $
0d60: 61 72 72 61 79 76 61 72 28 6c 6f 63 61 6c 5f 70  arrayvar(local_p
0d70: 61 79 6c 6f 61 64 5f 62 79 74 65 73 29 20 3d 20  ayload_bytes) = 
0d80: 20 4c 6f 63 61 6c 20 70 61 79 6c 6f 61 64 20 73   Local payload s
0d90: 69 7a 65 0a 23 20 20 20 24 61 72 72 61 79 76 61  ize.#   $arrayva
0da0: 72 28 70 61 72 65 6e 74 29 20 20 20 20 20 20 20  r(parent)       
0db0: 20 20 20 20 20 20 20 3d 20 20 50 61 72 65 6e 74         =  Parent
0dc0: 20 70 61 67 65 20 6e 75 6d 62 65 72 0a 23 20 0a   page number.# .
0dd0: 70 72 6f 63 20 63 75 72 73 6f 72 5f 69 6e 66 6f  proc cursor_info
0de0: 20 7b 61 72 72 61 79 76 61 72 20 63 73 72 20 7b   {arrayvar csr {
0df0: 75 70 20 30 7d 7d 20 7b 0a 20 20 75 70 76 61 72  up 0}} {.  upvar
0e00: 20 24 61 72 72 61 79 76 61 72 20 61 0a 20 20 66   $arrayvar a.  f
0e10: 6f 72 65 61 63 68 20 5b 6c 69 73 74 20 61 28 70  oreach [list a(p
0e20: 61 67 65 5f 6e 6f 29 20 5c 0a 20 20 20 20 20 20  age_no) \.      
0e30: 20 20 20 20 20 20 20 20 20 20 61 28 65 6e 74 72            a(entr
0e40: 79 5f 6e 6f 29 20 5c 0a 20 20 20 20 20 20 20 20  y_no) \.        
0e50: 20 20 20 20 20 20 20 20 61 28 70 61 67 65 5f 65          a(page_e
0e60: 6e 74 72 69 65 73 29 20 5c 0a 20 20 20 20 20 20  ntries) \.      
0e70: 20 20 20 20 20 20 20 20 20 20 61 28 63 65 6c 6c            a(cell
0e80: 5f 73 69 7a 65 29 20 5c 0a 20 20 20 20 20 20 20  _size) \.       
0e90: 20 20 20 20 20 20 20 20 20 61 28 70 61 67 65 5f           a(page_
0ea0: 66 72 65 65 62 79 74 65 73 29 20 5c 0a 20 20 20  freebytes) \.   
0eb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 61 28 70               a(p
0ec0: 61 67 65 5f 66 72 65 65 62 6c 6f 63 6b 73 29 20  age_freeblocks) 
0ed0: 5c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  \.              
0ee0: 20 20 61 28 70 61 79 6c 6f 61 64 5f 62 79 74 65    a(payload_byte
0ef0: 73 29 20 5c 0a 20 20 20 20 20 20 20 20 20 20 20  s) \.           
0f00: 20 20 20 20 20 61 28 68 65 61 64 65 72 5f 62 79       a(header_by
0f10: 74 65 73 29 20 5c 0a 20 20 20 20 20 20 20 20 20  tes) \.         
0f20: 20 20 20 20 20 20 20 61 28 6c 6f 63 61 6c 5f 70         a(local_p
0f30: 61 79 6c 6f 61 64 5f 62 79 74 65 73 29 20 5c 0a  ayload_bytes) \.
0f40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0f50: 61 28 70 61 72 65 6e 74 29 20 5d 20 5b 62 74 72  a(parent) ] [btr
0f60: 65 65 5f 63 75 72 73 6f 72 5f 69 6e 66 6f 20 24  ee_cursor_info $
0f70: 63 73 72 20 24 75 70 5d 20 7b 7d 0a 7d 0a 0a 23  csr $up] {}.}..#
0f80: 20 44 65 74 65 72 6d 69 6e 65 20 74 68 65 20 70   Determine the p
0f90: 61 67 65 2d 73 69 7a 65 20 6f 66 20 74 68 65 20  age-size of the 
0fa0: 64 61 74 61 62 61 73 65 2e 20 54 68 69 73 20 67  database. This g
0fb0: 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 20 69  lobal variable i
0fc0: 73 20 75 73 65 64 0a 23 20 74 68 72 6f 75 67 68  s used.# through
0fd0: 6f 75 74 20 74 68 65 20 73 63 72 69 70 74 2e 0a  out the script..
0fe0: 23 0a 73 65 74 20 70 61 67 65 53 69 7a 65 20 5b  #.set pageSize [
0ff0: 64 62 20 65 76 61 6c 20 7b 50 52 41 47 4d 41 20  db eval {PRAGMA 
1000: 70 61 67 65 5f 73 69 7a 65 7d 5d 0a 0a 23 20 41  page_size}]..# A
1010: 6e 61 6c 79 7a 65 20 65 76 65 72 79 20 74 61 62  nalyze every tab
1020: 6c 65 20 69 6e 20 74 68 65 20 64 61 74 61 62 61  le in the databa
1030: 73 65 2c 20 6f 6e 65 20 61 74 20 61 20 74 69 6d  se, one at a tim
1040: 65 2e 0a 23 0a 23 20 54 68 65 20 66 6f 6c 6c 6f  e..#.# The follo
1050: 77 69 6e 67 20 71 75 65 72 79 20 72 65 74 75 72  wing query retur
1060: 6e 73 20 74 68 65 20 6e 61 6d 65 20 61 6e 64 20  ns the name and 
1070: 72 6f 6f 74 2d 70 61 67 65 20 6f 66 20 65 61 63  root-page of eac
1080: 68 20 74 61 62 6c 65 20 69 6e 20 74 68 65 0a 23  h table in the.#
1090: 20 64 61 74 61 62 61 73 65 2c 20 69 6e 63 6c 75   database, inclu
10a0: 64 69 6e 67 20 74 68 65 20 73 71 6c 69 74 65 5f  ding the sqlite_
10b0: 6d 61 73 74 65 72 20 74 61 62 6c 65 2e 0a 23 0a  master table..#.
10c0: 73 65 74 20 73 71 6c 20 7b 0a 20 20 53 45 4c 45  set sql {.  SELE
10d0: 43 54 20 6e 61 6d 65 2c 20 72 6f 6f 74 70 61 67  CT name, rootpag
10e0: 65 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61  e FROM sqlite_ma
10f0: 73 74 65 72 20 57 48 45 52 45 20 74 79 70 65 3d  ster WHERE type=
1100: 27 74 61 62 6c 65 27 0a 20 20 55 4e 49 4f 4e 20  'table'.  UNION 
1110: 41 4c 4c 0a 20 20 53 45 4c 45 43 54 20 27 73 71  ALL.  SELECT 'sq
1120: 6c 69 74 65 5f 6d 61 73 74 65 72 27 2c 20 31 0a  lite_master', 1.
1130: 20 20 4f 52 44 45 52 20 42 59 20 31 0a 7d 0a 66    ORDER BY 1.}.f
1140: 6f 72 65 61 63 68 20 7b 6e 61 6d 65 20 72 6f 6f  oreach {name roo
1150: 74 70 61 67 65 7d 20 5b 64 62 20 65 76 61 6c 20  tpage} [db eval 
1160: 24 73 71 6c 5d 20 7b 0a 20 20 70 75 74 73 20 73  $sql] {.  puts s
1170: 74 64 65 72 72 20 22 41 6e 61 6c 79 7a 69 6e 67  tderr "Analyzing
1180: 20 74 61 62 6c 65 20 24 6e 61 6d 65 2e 2e 2e 22   table $name..."
1190: 0a 0a 20 20 23 20 43 6f 64 65 20 62 65 6c 6f 77  ..  # Code below
11a0: 20 74 72 61 76 65 72 73 65 73 20 74 68 65 20 74   traverses the t
11b0: 61 62 6c 65 20 62 65 69 6e 67 20 61 6e 61 6c 79  able being analy
11c0: 7a 65 64 20 28 74 61 62 6c 65 20 6e 61 6d 65 20  zed (table name 
11d0: 24 6e 61 6d 65 29 2c 20 75 73 69 6e 67 20 74 68  $name), using th
11e0: 65 0a 20 20 23 20 62 74 72 65 65 20 63 75 72 73  e.  # btree curs
11f0: 6f 72 20 24 63 75 72 73 6f 72 2e 20 53 74 61 74  or $cursor. Stat
1200: 69 73 74 69 63 73 20 72 65 6c 61 74 65 64 20 74  istics related t
1210: 6f 20 74 61 62 6c 65 20 24 6e 61 6d 65 20 61 72  o table $name ar
1220: 65 20 61 63 63 75 6d 75 6c 61 74 65 64 20 69 6e  e accumulated in
1230: 0a 20 20 23 20 74 68 65 20 66 6f 6c 6c 6f 77 69  .  # the followi
1240: 6e 67 20 76 61 72 69 61 62 6c 65 73 3a 0a 20 20  ng variables:.  
1250: 23 0a 20 20 73 65 74 20 74 6f 74 61 6c 5f 70 61  #.  set total_pa
1260: 79 6c 6f 61 64 20 30 20 20 20 20 20 20 20 20 3b  yload 0        ;
1270: 23 20 50 61 79 6c 6f 61 64 20 73 70 61 63 65 20  # Payload space 
1280: 75 73 65 64 20 62 79 20 61 6c 6c 20 65 6e 74 72  used by all entr
1290: 69 65 73 0a 20 20 73 65 74 20 74 6f 74 61 6c 5f  ies.  set total_
12a0: 6f 76 66 6c 20 30 20 20 20 20 20 20 20 20 20 20  ovfl 0          
12b0: 20 3b 23 20 50 61 79 6c 6f 61 64 20 73 70 61 63   ;# Payload spac
12c0: 65 20 6f 6e 20 6f 76 65 72 66 6c 6f 77 20 70 61  e on overflow pa
12d0: 67 65 73 0a 20 20 73 65 74 20 75 6e 75 73 65 64  ges.  set unused
12e0: 5f 69 6e 74 20 30 20 20 20 20 20 20 20 20 20 20  _int 0          
12f0: 20 3b 23 20 55 6e 75 73 65 64 20 73 70 61 63 65   ;# Unused space
1300: 20 6f 6e 20 69 6e 74 65 72 69 6f 72 20 6e 6f 64   on interior nod
1310: 65 73 0a 20 20 73 65 74 20 75 6e 75 73 65 64 5f  es.  set unused_
1320: 6c 65 61 66 20 30 20 20 20 20 20 20 20 20 20 20  leaf 0          
1330: 3b 23 20 55 6e 75 73 65 64 20 73 70 61 63 65 20  ;# Unused space 
1340: 6f 6e 20 6c 65 61 66 20 6e 6f 64 65 73 0a 20 20  on leaf nodes.  
1350: 73 65 74 20 75 6e 75 73 65 64 5f 6f 76 66 6c 20  set unused_ovfl 
1360: 30 20 20 20 20 20 20 20 20 20 20 3b 23 20 55 6e  0          ;# Un
1370: 75 73 65 64 20 73 70 61 63 65 20 6f 6e 20 6f 76  used space on ov
1380: 65 72 66 6c 6f 77 20 70 61 67 65 73 0a 20 20 73  erflow pages.  s
1390: 65 74 20 63 6e 74 5f 6f 76 66 6c 20 30 20 20 20  et cnt_ovfl 0   
13a0: 20 20 20 20 20 20 20 20 20 20 3b 23 20 4e 75 6d            ;# Num
13b0: 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20 74  ber of entries t
13c0: 68 61 74 20 75 73 65 20 6f 76 65 72 66 6c 6f 77  hat use overflow
13d0: 73 0a 20 20 73 65 74 20 63 6e 74 5f 6c 65 61 66  s.  set cnt_leaf
13e0: 5f 65 6e 74 72 79 20 30 20 20 20 20 20 20 20 3b  _entry 0       ;
13f0: 23 20 4e 75 6d 62 65 72 20 6f 66 20 6c 65 61 66  # Number of leaf
1400: 20 65 6e 74 72 69 65 73 0a 20 20 73 65 74 20 63   entries.  set c
1410: 6e 74 5f 69 6e 74 5f 65 6e 74 72 79 20 30 20 20  nt_int_entry 0  
1420: 20 20 20 20 20 20 3b 23 20 4e 75 6d 62 65 72 20        ;# Number 
1430: 6f 66 20 69 6e 74 65 72 6f 72 20 65 6e 74 72 69  of interor entri
1440: 65 73 0a 20 20 73 65 74 20 6d 78 5f 70 61 79 6c  es.  set mx_payl
1450: 6f 61 64 20 30 20 20 20 20 20 20 20 20 20 20 20  oad 0           
1460: 3b 23 20 4d 61 78 69 6d 75 6d 20 70 61 79 6c 6f  ;# Maximum paylo
1470: 61 64 20 73 69 7a 65 0a 20 20 73 65 74 20 6f 76  ad size.  set ov
1480: 66 6c 5f 70 61 67 65 73 20 30 20 20 20 20 20 20  fl_pages 0      
1490: 20 20 20 20 20 3b 23 20 4e 75 6d 62 65 72 20 6f       ;# Number o
14a0: 66 20 6f 76 65 72 66 6c 6f 77 20 70 61 67 65 73  f overflow pages
14b0: 20 75 73 65 64 0a 20 20 73 65 74 20 6c 65 61 66   used.  set leaf
14c0: 5f 70 61 67 65 73 20 30 20 20 20 20 20 20 20 20  _pages 0        
14d0: 20 20 20 3b 23 20 4e 75 6d 62 65 72 20 6f 66 20     ;# Number of 
14e0: 6c 65 61 66 20 70 61 67 65 73 0a 20 20 73 65 74  leaf pages.  set
14f0: 20 69 6e 74 5f 70 61 67 65 73 20 30 20 20 20 20   int_pages 0    
1500: 20 20 20 20 20 20 20 20 3b 23 20 4e 75 6d 62 65          ;# Numbe
1510: 72 20 6f 66 20 69 6e 74 65 72 69 6f 72 20 70 61  r of interior pa
1520: 67 65 73 0a 0a 20 20 23 20 41 73 20 74 68 65 20  ges..  # As the 
1530: 62 74 72 65 65 20 69 73 20 74 72 61 76 65 72 73  btree is travers
1540: 65 64 2c 20 74 68 65 20 61 72 72 61 79 20 76 61  ed, the array va
1550: 72 69 61 62 6c 65 20 24 73 65 65 6e 28 24 70 67  riable $seen($pg
1560: 6e 6f 29 20 69 73 20 73 65 74 20 74 6f 20 31 0a  no) is set to 1.
1570: 20 20 23 20 74 68 65 20 66 69 72 73 74 20 74 69    # the first ti
1580: 6d 65 20 70 61 67 65 20 24 70 67 6e 6f 20 69 73  me page $pgno is
1590: 20 65 6e 63 6f 75 6e 74 65 72 65 64 2e 0a 20 20   encountered..  
15a0: 23 0a 20 20 63 61 74 63 68 20 7b 75 6e 73 65 74  #.  catch {unset
15b0: 20 73 65 65 6e 7d 0a 0a 20 20 23 20 54 68 65 20   seen}..  # The 
15c0: 66 6f 6c 6c 6f 77 69 6e 67 20 6c 6f 6f 70 20 72  following loop r
15d0: 75 6e 73 20 6f 6e 63 65 20 66 6f 72 20 65 61 63  uns once for eac
15e0: 68 20 65 6e 74 72 79 20 69 6e 20 74 61 62 6c 65  h entry in table
15f0: 20 24 6e 61 6d 65 2e 20 54 68 65 20 74 61 62 6c   $name. The tabl
1600: 65 0a 20 20 23 20 69 73 20 74 72 61 76 65 72 73  e.  # is travers
1610: 65 64 20 75 73 69 6e 67 20 74 68 65 20 62 74 72  ed using the btr
1620: 65 65 20 63 75 72 73 6f 72 20 73 74 6f 72 65 64  ee cursor stored
1630: 20 69 6e 20 76 61 72 69 61 62 6c 65 20 24 63 73   in variable $cs
1640: 72 0a 20 20 23 0a 20 20 73 65 74 20 63 73 72 20  r.  #.  set csr 
1650: 5b 62 74 72 65 65 5f 63 75 72 73 6f 72 20 24 44  [btree_cursor $D
1660: 42 20 24 72 6f 6f 74 70 61 67 65 20 30 5d 0a 20  B $rootpage 0]. 
1670: 20 66 6f 72 20 7b 62 74 72 65 65 5f 66 69 72 73   for {btree_firs
1680: 74 20 24 63 73 72 7d 20 7b 21 5b 62 74 72 65 65  t $csr} {![btree
1690: 5f 65 6f 66 20 24 63 73 72 5d 7d 20 7b 62 74 72  _eof $csr]} {btr
16a0: 65 65 5f 6e 65 78 74 20 24 63 73 72 7d 20 7b 0a  ee_next $csr} {.
16b0: 20 20 20 20 69 6e 63 72 20 63 6e 74 5f 6c 65 61      incr cnt_lea
16c0: 66 5f 65 6e 74 72 79 0a 0a 20 20 20 20 23 20 52  f_entry..    # R
16d0: 65 74 72 69 65 76 65 20 69 6e 66 6f 72 6d 61 74  etrieve informat
16e0: 69 6f 6e 20 61 62 6f 75 74 20 74 68 65 20 65 6e  ion about the en
16f0: 74 72 79 20 74 68 65 20 62 74 72 65 65 2d 63 75  try the btree-cu
1700: 72 73 6f 72 20 70 6f 69 6e 74 73 20 74 6f 20 69  rsor points to i
1710: 6e 74 6f 0a 20 20 20 20 23 20 74 68 65 20 61 72  nto.    # the ar
1720: 72 61 79 20 76 61 72 69 61 62 6c 65 20 24 63 69  ray variable $ci
1730: 20 28 63 75 72 73 6f 72 20 69 6e 66 6f 29 2e 0a   (cursor info)..
1740: 20 20 20 20 23 0a 20 20 20 20 63 75 72 73 6f 72      #.    cursor
1750: 5f 69 6e 66 6f 20 63 69 20 24 63 73 72 0a 0a 20  _info ci $csr.. 
1760: 20 20 20 23 20 43 68 65 63 6b 20 69 66 20 74 68     # Check if th
1770: 65 20 70 61 79 6c 6f 61 64 20 6f 66 20 74 68 69  e payload of thi
1780: 73 20 65 6e 74 72 79 20 69 73 20 67 72 65 61 74  s entry is great
1790: 65 72 20 74 68 61 6e 20 74 68 65 20 63 75 72 72  er than the curr
17a0: 65 6e 74 20 0a 20 20 20 20 23 20 24 6d 78 5f 70  ent .    # $mx_p
17b0: 61 79 6c 6f 61 64 20 73 74 61 74 69 73 74 69 63  ayload statistic
17c0: 20 66 6f 72 20 74 68 65 20 74 61 62 6c 65 2e 20   for the table. 
17d0: 41 6c 73 6f 20 69 6e 63 72 65 61 73 65 20 74 68  Also increase th
17e0: 65 20 24 74 6f 74 61 6c 5f 70 61 79 6c 6f 61 64  e $total_payload
17f0: 0a 20 20 20 20 23 20 73 74 61 74 69 73 74 69 63  .    # statistic
1800: 2e 0a 20 20 20 20 23 0a 20 20 20 20 69 66 20 7b  ..    #.    if {
1810: 24 63 69 28 70 61 79 6c 6f 61 64 5f 62 79 74 65  $ci(payload_byte
1820: 73 29 3e 24 6d 78 5f 70 61 79 6c 6f 61 64 7d 20  s)>$mx_payload} 
1830: 7b 73 65 74 20 6d 78 5f 70 61 79 6c 6f 61 64 20  {set mx_payload 
1840: 24 63 69 28 70 61 79 6c 6f 61 64 5f 62 79 74 65  $ci(payload_byte
1850: 73 29 7d 0a 20 20 20 20 69 6e 63 72 20 74 6f 74  s)}.    incr tot
1860: 61 6c 5f 70 61 79 6c 6f 61 64 20 24 63 69 28 70  al_payload $ci(p
1870: 61 79 6c 6f 61 64 5f 62 79 74 65 73 29 0a 0a 20  ayload_bytes).. 
1880: 20 20 20 23 20 49 66 20 74 68 69 73 20 65 6e 74     # If this ent
1890: 72 79 20 75 73 65 73 20 6f 76 65 72 66 6c 6f 77  ry uses overflow
18a0: 20 70 61 67 65 73 2c 20 74 68 65 6e 20 75 70 64   pages, then upd
18b0: 61 74 65 20 74 68 65 20 24 63 6e 74 5f 6f 76 66  ate the $cnt_ovf
18c0: 6c 2c 20 0a 20 20 20 20 23 20 24 74 6f 74 61 6c  l, .    # $total
18d0: 5f 6f 76 66 6c 2c 20 24 6f 76 66 6c 5f 70 61 67  _ovfl, $ovfl_pag
18e0: 65 73 20 61 6e 64 20 24 75 6e 75 73 65 64 5f 6f  es and $unused_o
18f0: 76 66 6c 20 73 74 61 74 69 73 74 69 63 73 2e 0a  vfl statistics..
1900: 20 20 20 20 23 0a 20 20 20 20 73 65 74 20 6f 76      #.    set ov
1910: 66 6c 20 5b 65 78 70 72 20 7b 24 63 69 28 70 61  fl [expr {$ci(pa
1920: 79 6c 6f 61 64 5f 62 79 74 65 73 29 2d 24 63 69  yload_bytes)-$ci
1930: 28 6c 6f 63 61 6c 5f 70 61 79 6c 6f 61 64 5f 62  (local_payload_b
1940: 79 74 65 73 29 7d 5d 0a 20 20 20 20 69 66 20 7b  ytes)}].    if {
1950: 24 6f 76 66 6c 7d 20 7b 0a 20 20 20 20 20 20 69  $ovfl} {.      i
1960: 6e 63 72 20 63 6e 74 5f 6f 76 66 6c 0a 20 20 20  ncr cnt_ovfl.   
1970: 20 20 20 69 6e 63 72 20 74 6f 74 61 6c 5f 6f 76     incr total_ov
1980: 66 6c 20 24 6f 76 66 6c 0a 20 20 20 20 20 20 73  fl $ovfl.      s
1990: 65 74 20 6e 20 5b 65 78 70 72 20 7b 69 6e 74 28  et n [expr {int(
19a0: 63 65 69 6c 28 24 6f 76 66 6c 2f 28 24 70 61 67  ceil($ovfl/($pag
19b0: 65 53 69 7a 65 2d 34 2e 30 29 29 29 7d 5d 0a 20  eSize-4.0)))}]. 
19c0: 20 20 20 20 20 69 6e 63 72 20 6f 76 66 6c 5f 70       incr ovfl_p
19d0: 61 67 65 73 20 24 6e 0a 20 20 20 20 20 20 69 6e  ages $n.      in
19e0: 63 72 20 75 6e 75 73 65 64 5f 6f 76 66 6c 20 5b  cr unused_ovfl [
19f0: 65 78 70 72 20 7b 24 6e 2a 28 24 70 61 67 65 53  expr {$n*($pageS
1a00: 69 7a 65 2d 34 29 20 2d 20 24 6f 76 66 6c 7d 5d  ize-4) - $ovfl}]
1a10: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 23 20 49 66  .    }..    # If
1a20: 20 74 68 69 73 20 69 73 20 74 68 65 20 66 69 72   this is the fir
1a30: 73 74 20 74 61 62 6c 65 20 65 6e 74 72 79 20 61  st table entry a
1a40: 6e 61 6c 79 7a 65 64 20 66 6f 72 20 74 68 65 20  nalyzed for the 
1a50: 70 61 67 65 2c 20 74 68 65 6e 20 75 70 64 61 74  page, then updat
1a60: 65 0a 20 20 20 20 23 20 74 68 65 20 70 61 67 65  e.    # the page
1a70: 2d 72 65 6c 61 74 65 64 20 73 74 61 74 69 73 74  -related statist
1a80: 69 63 73 20 24 6c 65 61 66 5f 70 61 67 65 73 20  ics $leaf_pages 
1a90: 61 6e 64 20 24 75 6e 75 73 65 64 5f 6c 65 61 66  and $unused_leaf
1aa0: 2e 20 41 6c 73 6f 2c 20 69 66 0a 20 20 20 20 23  . Also, if.    #
1ab0: 20 74 68 69 73 20 70 61 67 65 20 68 61 73 20 61   this page has a
1ac0: 20 70 61 72 65 6e 74 20 70 61 67 65 20 74 68 61   parent page tha
1ad0: 74 20 68 61 73 20 6e 6f 74 20 62 65 65 6e 20 61  t has not been a
1ae0: 6e 61 6c 79 7a 65 64 2c 20 72 65 74 72 69 65 76  nalyzed, retriev
1af0: 65 0a 20 20 20 20 23 20 69 6e 66 6f 20 66 6f 72  e.    # info for
1b00: 20 74 68 65 20 70 61 72 65 6e 74 20 61 6e 64 20   the parent and 
1b10: 75 70 64 61 74 65 20 73 74 61 74 69 73 74 69 63  update statistic
1b20: 73 20 66 6f 72 20 69 74 20 74 6f 6f 2e 0a 20 20  s for it too..  
1b30: 20 20 23 0a 20 20 20 20 69 66 20 7b 21 5b 69 6e    #.    if {![in
1b40: 66 6f 20 65 78 69 73 74 73 20 73 65 65 6e 28 24  fo exists seen($
1b50: 63 69 28 70 61 67 65 5f 6e 6f 29 29 5d 7d 20 7b  ci(page_no))]} {
1b60: 0a 20 20 20 20 20 20 73 65 74 20 73 65 65 6e 28  .      set seen(
1b70: 24 63 69 28 70 61 67 65 5f 6e 6f 29 29 20 31 0a  $ci(page_no)) 1.
1b80: 20 20 20 20 20 20 69 6e 63 72 20 6c 65 61 66 5f        incr leaf_
1b90: 70 61 67 65 73 0a 20 20 20 20 20 20 69 6e 63 72  pages.      incr
1ba0: 20 75 6e 75 73 65 64 5f 6c 65 61 66 20 24 63 69   unused_leaf $ci
1bb0: 28 70 61 67 65 5f 66 72 65 65 62 79 74 65 73 29  (page_freebytes)
1bc0: 0a 0a 20 20 20 20 20 20 23 20 4e 6f 77 20 63 68  ..      # Now ch
1bd0: 65 63 6b 20 69 66 20 74 68 65 20 70 61 67 65 20  eck if the page 
1be0: 68 61 73 20 61 20 70 61 72 65 6e 74 20 74 68 61  has a parent tha
1bf0: 74 20 68 61 73 20 6e 6f 74 20 62 65 65 6e 20 61  t has not been a
1c00: 6e 61 6c 79 7a 65 64 2e 20 49 66 0a 20 20 20 20  nalyzed. If.    
1c10: 20 20 23 20 73 6f 2c 20 75 70 64 61 74 65 20 74    # so, update t
1c20: 68 65 20 24 69 6e 74 5f 70 61 67 65 73 2c 20 24  he $int_pages, $
1c30: 63 6e 74 5f 69 6e 74 5f 65 6e 74 72 79 20 61 6e  cnt_int_entry an
1c40: 64 20 24 75 6e 75 73 65 64 5f 69 6e 74 20 73 74  d $unused_int st
1c50: 61 74 69 73 74 69 63 73 0a 20 20 20 20 20 20 23  atistics.      #
1c60: 20 61 63 63 6f 72 64 69 6e 67 6c 79 2e 20 54 68   accordingly. Th
1c70: 65 6e 20 63 68 65 63 6b 20 69 66 20 74 68 65 20  en check if the 
1c80: 70 61 72 65 6e 74 20 70 61 67 65 20 68 61 73 20  parent page has 
1c90: 61 20 70 61 72 65 6e 74 20 74 68 61 74 20 68 61  a parent that ha
1ca0: 73 0a 20 20 20 20 20 20 23 20 6e 6f 74 20 79 65  s.      # not ye
1cb0: 74 20 62 65 65 6e 20 61 6e 61 6c 79 7a 65 64 20  t been analyzed 
1cc0: 65 74 63 2e 0a 20 20 20 20 20 20 23 0a 20 20 20  etc..      #.   
1cd0: 20 20 20 23 20 73 65 74 20 70 61 72 65 6e 74 20     # set parent 
1ce0: 24 63 69 28 70 61 72 65 6e 74 5f 70 61 67 65 5f  $ci(parent_page_
1cf0: 6e 6f 29 0a 20 20 20 20 20 20 66 6f 72 20 7b 73  no).      for {s
1d00: 65 74 20 75 70 20 31 7d 20 5c 0a 20 20 20 20 20  et up 1} \.     
1d10: 20 20 20 20 20 7b 24 63 69 28 70 61 72 65 6e 74       {$ci(parent
1d20: 29 21 3d 30 20 26 26 20 21 5b 69 6e 66 6f 20 65  )!=0 && ![info e
1d30: 78 69 73 74 73 20 73 65 65 6e 28 24 63 69 28 70  xists seen($ci(p
1d40: 61 72 65 6e 74 29 29 5d 7d 20 7b 69 6e 63 72 20  arent))]} {incr 
1d50: 75 70 7d 20 5c 0a 20 20 20 20 20 20 7b 0a 20 20  up} \.      {.  
1d60: 20 20 20 20 20 20 23 20 4d 61 72 6b 20 74 68 65        # Mark the
1d70: 20 70 61 72 65 6e 74 20 61 73 20 73 65 65 6e 2e   parent as seen.
1d80: 0a 20 20 20 20 20 20 20 20 23 0a 20 20 20 20 20  .        #.     
1d90: 20 20 20 73 65 74 20 73 65 65 6e 28 24 63 69 28     set seen($ci(
1da0: 70 61 72 65 6e 74 29 29 20 31 0a 0a 20 20 20 20  parent)) 1..    
1db0: 20 20 20 20 23 20 52 65 74 72 69 65 76 65 20 69      # Retrieve i
1dc0: 6e 66 6f 20 66 6f 72 20 74 68 65 20 70 61 72 65  nfo for the pare
1dd0: 6e 74 20 61 6e 64 20 75 70 64 61 74 65 20 73 74  nt and update st
1de0: 61 74 69 73 74 69 63 73 2e 0a 20 20 20 20 20 20  atistics..      
1df0: 20 20 63 75 72 73 6f 72 5f 69 6e 66 6f 20 63 69    cursor_info ci
1e00: 20 24 63 73 72 20 24 75 70 0a 20 20 20 20 20 20   $csr $up.      
1e10: 20 20 69 6e 63 72 20 69 6e 74 5f 70 61 67 65 73    incr int_pages
1e20: 0a 20 20 20 20 20 20 20 20 69 6e 63 72 20 63 6e  .        incr cn
1e30: 74 5f 69 6e 74 5f 65 6e 74 72 79 20 24 63 69 28  t_int_entry $ci(
1e40: 70 61 67 65 5f 65 6e 74 72 69 65 73 29 0a 20 20  page_entries).  
1e50: 20 20 20 20 20 20 69 6e 63 72 20 75 6e 75 73 65        incr unuse
1e60: 64 5f 69 6e 74 20 24 63 69 28 70 61 67 65 5f 66  d_int $ci(page_f
1e70: 72 65 65 62 79 74 65 73 29 0a 20 20 20 20 20 20  reebytes).      
1e80: 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 62 74  }.    }.  }.  bt
1e90: 72 65 65 5f 63 6c 6f 73 65 5f 63 75 72 73 6f 72  ree_close_cursor
1ea0: 20 24 63 73 72 0a 0a 20 20 23 20 48 61 6e 64 6c   $csr..  # Handl
1eb0: 65 20 74 68 65 20 73 70 65 63 69 61 6c 20 63 61  e the special ca
1ec0: 73 65 20 77 68 65 72 65 20 61 20 74 61 62 6c 65  se where a table
1ed0: 20 63 6f 6e 74 61 69 6e 73 20 6e 6f 20 64 61 74   contains no dat
1ee0: 61 2e 20 49 6e 20 74 68 69 73 20 63 61 73 65 0a  a. In this case.
1ef0: 20 20 23 20 61 6c 6c 20 73 74 61 74 69 73 74 69    # all statisti
1f00: 63 73 20 61 72 65 20 7a 65 72 6f 2c 20 65 78 63  cs are zero, exc
1f10: 65 70 74 20 66 6f 72 20 74 68 65 20 6e 75 6d 62  ept for the numb
1f20: 65 72 20 6f 66 20 6c 65 61 66 20 70 61 67 65 73  er of leaf pages
1f30: 20 28 31 29 20 61 6e 64 0a 20 20 23 20 74 68 65   (1) and.  # the
1f40: 20 75 6e 75 73 65 64 20 62 79 74 65 73 20 6f 6e   unused bytes on
1f50: 20 6c 65 61 66 20 70 61 67 65 73 20 28 24 70 61   leaf pages ($pa
1f60: 67 65 53 69 7a 65 20 2d 20 38 29 2e 0a 20 20 23  geSize - 8)..  #
1f70: 0a 20 20 23 20 41 6e 20 65 78 63 65 70 74 69 6f  .  # An exceptio
1f80: 6e 20 74 6f 20 74 68 65 20 61 62 6f 76 65 20 69  n to the above i
1f90: 73 20 74 68 65 20 73 71 6c 69 74 65 5f 6d 61 73  s the sqlite_mas
1fa0: 74 65 72 20 74 61 62 6c 65 2e 20 49 66 20 69 74  ter table. If it
1fb0: 20 69 73 20 65 6d 70 74 79 0a 20 20 23 20 74 68   is empty.  # th
1fc0: 65 6e 20 61 6c 6c 20 73 74 61 74 69 73 74 69 63  en all statistic
1fd0: 73 20 61 72 65 20 7a 65 72 6f 20 65 78 63 65 70  s are zero excep
1fe0: 74 20 66 6f 72 20 74 68 65 20 6e 75 6d 62 65 72  t for the number
1ff0: 20 6f 66 20 6c 65 61 66 20 70 61 67 65 73 20 28   of leaf pages (
2000: 31 29 2c 0a 20 20 23 20 61 6e 64 20 74 68 65 20  1),.  # and the 
2010: 6e 75 6d 62 65 72 20 6f 66 20 75 6e 75 73 65 64  number of unused
2020: 20 62 79 74 65 73 20 6f 6e 20 6c 65 61 66 20 70   bytes on leaf p
2030: 61 67 65 73 20 28 24 70 61 67 65 53 69 7a 65 20  ages ($pageSize 
2040: 2d 20 31 31 32 29 2e 0a 20 20 23 0a 20 20 69 66  - 112)..  #.  if
2050: 20 7b 5b 6c 6c 65 6e 67 74 68 20 5b 61 72 72 61   {[llength [arra
2060: 79 20 6e 61 6d 65 73 20 73 65 65 6e 5d 5d 3d 3d  y names seen]]==
2070: 30 7d 20 7b 0a 20 20 20 20 73 65 74 20 6c 65 61  0} {.    set lea
2080: 66 5f 70 61 67 65 73 20 31 0a 20 20 20 20 69 66  f_pages 1.    if
2090: 20 7b 24 72 6f 6f 74 70 61 67 65 3d 3d 31 7d 20   {$rootpage==1} 
20a0: 7b 0a 20 20 20 20 20 20 73 65 74 20 75 6e 75 73  {.      set unus
20b0: 65 64 5f 6c 65 61 66 20 5b 65 78 70 72 20 7b 24  ed_leaf [expr {$
20c0: 70 61 67 65 53 69 7a 65 2d 31 31 32 7d 5d 0a 20  pageSize-112}]. 
20d0: 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20     } else {.    
20e0: 20 20 73 65 74 20 75 6e 75 73 65 64 5f 6c 65 61    set unused_lea
20f0: 66 20 5b 65 78 70 72 20 7b 24 70 61 67 65 53 69  f [expr {$pageSi
2100: 7a 65 2d 38 7d 5d 0a 20 20 20 20 7d 0a 20 20 7d  ze-8}].    }.  }
2110: 0a 0a 20 20 23 20 49 6e 73 65 72 74 20 74 68 65  ..  # Insert the
2120: 20 73 74 61 74 69 73 74 69 63 73 20 66 6f 72 20   statistics for 
2130: 74 68 65 20 74 61 62 6c 65 20 61 6e 61 6c 79 7a  the table analyz
2140: 65 64 20 69 6e 74 6f 20 74 68 65 20 69 6e 2d 6d  ed into the in-m
2150: 65 6d 6f 72 79 20 64 61 74 61 62 61 73 65 2e 0a  emory database..
2160: 20 20 23 0a 20 20 73 65 74 20 73 71 6c 20 22 49    #.  set sql "I
2170: 4e 53 45 52 54 20 49 4e 54 4f 20 73 70 61 63 65  NSERT INTO space
2180: 5f 75 73 65 64 20 56 41 4c 55 45 53 28 22 0a 20  _used VALUES(". 
2190: 20 61 70 70 65 6e 64 20 73 71 6c 20 5b 71 75 6f   append sql [quo
21a0: 74 65 20 24 6e 61 6d 65 5d 0a 20 20 61 70 70 65  te $name].  appe
21b0: 6e 64 20 73 71 6c 20 22 2c 5b 71 75 6f 74 65 20  nd sql ",[quote 
21c0: 24 6e 61 6d 65 5d 22 0a 20 20 61 70 70 65 6e 64  $name]".  append
21d0: 20 73 71 6c 20 22 2c 30 22 0a 20 20 61 70 70 65   sql ",0".  appe
21e0: 6e 64 20 73 71 6c 20 22 2c 5b 65 78 70 72 20 7b  nd sql ",[expr {
21f0: 24 63 6e 74 5f 6c 65 61 66 5f 65 6e 74 72 79 2b  $cnt_leaf_entry+
2200: 24 63 6e 74 5f 69 6e 74 5f 65 6e 74 72 79 7d 5d  $cnt_int_entry}]
2210: 22 0a 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22  ".  append sql "
2220: 2c 24 63 6e 74 5f 6c 65 61 66 5f 65 6e 74 72 79  ,$cnt_leaf_entry
2230: 22 0a 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22  ".  append sql "
2240: 2c 24 74 6f 74 61 6c 5f 70 61 79 6c 6f 61 64 22  ,$total_payload"
2250: 0a 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22 2c  .  append sql ",
2260: 24 74 6f 74 61 6c 5f 6f 76 66 6c 22 0a 20 20 61  $total_ovfl".  a
2270: 70 70 65 6e 64 20 73 71 6c 20 22 2c 24 63 6e 74  ppend sql ",$cnt
2280: 5f 6f 76 66 6c 22 0a 20 20 61 70 70 65 6e 64 20  _ovfl".  append 
2290: 73 71 6c 20 22 2c 24 6d 78 5f 70 61 79 6c 6f 61  sql ",$mx_payloa
22a0: 64 22 0a 20 20 61 70 70 65 6e 64 20 73 71 6c 20  d".  append sql 
22b0: 22 2c 24 69 6e 74 5f 70 61 67 65 73 22 0a 20 20  ",$int_pages".  
22c0: 61 70 70 65 6e 64 20 73 71 6c 20 22 2c 24 6c 65  append sql ",$le
22d0: 61 66 5f 70 61 67 65 73 22 0a 20 20 61 70 70 65  af_pages".  appe
22e0: 6e 64 20 73 71 6c 20 22 2c 24 6f 76 66 6c 5f 70  nd sql ",$ovfl_p
22f0: 61 67 65 73 22 0a 20 20 61 70 70 65 6e 64 20 73  ages".  append s
2300: 71 6c 20 22 2c 24 75 6e 75 73 65 64 5f 69 6e 74  ql ",$unused_int
2310: 22 0a 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22  ".  append sql "
2320: 2c 24 75 6e 75 73 65 64 5f 6c 65 61 66 22 0a 20  ,$unused_leaf". 
2330: 20 61 70 70 65 6e 64 20 73 71 6c 20 22 2c 24 75   append sql ",$u
2340: 6e 75 73 65 64 5f 6f 76 66 6c 22 0a 20 20 61 70  nused_ovfl".  ap
2350: 70 65 6e 64 20 73 71 6c 20 29 3b 0a 20 20 6d 65  pend sql );.  me
2360: 6d 20 65 76 61 6c 20 24 73 71 6c 0a 7d 0a 0a 23  m eval $sql.}..#
2370: 20 41 6e 61 6c 79 7a 65 20 65 76 65 72 79 20 69   Analyze every i
2380: 6e 64 65 78 20 69 6e 20 74 68 65 20 64 61 74 61  ndex in the data
2390: 62 61 73 65 2c 20 6f 6e 65 20 61 74 20 61 20 74  base, one at a t
23a0: 69 6d 65 2e 0a 23 0a 23 20 54 68 65 20 71 75 65  ime..#.# The que
23b0: 72 79 20 62 65 6c 6f 77 20 72 65 74 75 72 6e 73  ry below returns
23c0: 20 74 68 65 20 6e 61 6d 65 2c 20 61 73 73 6f 63   the name, assoc
23d0: 69 61 74 65 64 20 74 61 62 6c 65 20 61 6e 64 20  iated table and 
23e0: 72 6f 6f 74 2d 70 61 67 65 20 6e 75 6d 62 65 72  root-page number
23f0: 20 0a 23 20 66 6f 72 20 65 76 65 72 79 20 69 6e   .# for every in
2400: 64 65 78 20 69 6e 20 74 68 65 20 64 61 74 61 62  dex in the datab
2410: 61 73 65 2e 0a 23 0a 73 65 74 20 73 71 6c 20 7b  ase..#.set sql {
2420: 0a 20 20 53 45 4c 45 43 54 20 6e 61 6d 65 2c 20  .  SELECT name, 
2430: 74 62 6c 5f 6e 61 6d 65 2c 20 72 6f 6f 74 70 61  tbl_name, rootpa
2440: 67 65 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d  ge FROM sqlite_m
2450: 61 73 74 65 72 20 57 48 45 52 45 20 74 79 70 65  aster WHERE type
2460: 3d 27 69 6e 64 65 78 27 0a 20 20 4f 52 44 45 52  ='index'.  ORDER
2470: 20 42 59 20 32 2c 20 31 0a 7d 0a 66 6f 72 65 61   BY 2, 1.}.forea
2480: 63 68 20 7b 6e 61 6d 65 20 74 62 6c 5f 6e 61 6d  ch {name tbl_nam
2490: 65 20 72 6f 6f 74 70 61 67 65 7d 20 5b 64 62 20  e rootpage} [db 
24a0: 65 76 61 6c 20 24 73 71 6c 5d 20 7b 0a 20 20 70  eval $sql] {.  p
24b0: 75 74 73 20 73 74 64 65 72 72 20 22 41 6e 61 6c  uts stderr "Anal
24c0: 79 7a 69 6e 67 20 69 6e 64 65 78 20 24 6e 61 6d  yzing index $nam
24d0: 65 20 6f 66 20 74 61 62 6c 65 20 24 74 62 6c 5f  e of table $tbl_
24e0: 6e 61 6d 65 2e 2e 2e 22 0a 0a 20 20 23 20 43 6f  name..."..  # Co
24f0: 64 65 20 62 65 6c 6f 77 20 74 72 61 76 65 72 73  de below travers
2500: 65 73 20 74 68 65 20 69 6e 64 65 78 20 62 65 69  es the index bei
2510: 6e 67 20 61 6e 61 6c 79 7a 65 64 20 28 69 6e 64  ng analyzed (ind
2520: 65 78 20 6e 61 6d 65 20 24 6e 61 6d 65 29 2c 20  ex name $name), 
2530: 75 73 69 6e 67 20 74 68 65 0a 20 20 23 20 62 74  using the.  # bt
2540: 72 65 65 20 63 75 72 73 6f 72 20 24 63 75 72 73  ree cursor $curs
2550: 6f 72 2e 20 53 74 61 74 69 73 74 69 63 73 20 72  or. Statistics r
2560: 65 6c 61 74 65 64 20 74 6f 20 69 6e 64 65 78 20  elated to index 
2570: 24 6e 61 6d 65 20 61 72 65 20 61 63 63 75 6d 75  $name are accumu
2580: 6c 61 74 65 64 20 69 6e 0a 20 20 23 20 74 68 65  lated in.  # the
2590: 20 66 6f 6c 6c 6f 77 69 6e 67 20 76 61 72 69 61   following varia
25a0: 62 6c 65 73 3a 0a 20 20 23 0a 20 20 73 65 74 20  bles:.  #.  set 
25b0: 74 6f 74 61 6c 5f 70 61 79 6c 6f 61 64 20 30 20  total_payload 0 
25c0: 20 20 20 20 20 20 20 3b 23 20 50 61 79 6c 6f 61         ;# Payloa
25d0: 64 20 73 70 61 63 65 20 75 73 65 64 20 62 79 20  d space used by 
25e0: 61 6c 6c 20 65 6e 74 72 69 65 73 0a 20 20 73 65  all entries.  se
25f0: 74 20 74 6f 74 61 6c 5f 6f 76 66 6c 20 30 20 20  t total_ovfl 0  
2600: 20 20 20 20 20 20 20 20 20 3b 23 20 50 61 79 6c           ;# Payl
2610: 6f 61 64 20 73 70 61 63 65 20 6f 6e 20 6f 76 65  oad space on ove
2620: 72 66 6c 6f 77 20 70 61 67 65 73 0a 20 20 73 65  rflow pages.  se
2630: 74 20 75 6e 75 73 65 64 5f 6c 65 61 66 20 30 20  t unused_leaf 0 
2640: 20 20 20 20 20 20 20 20 20 3b 23 20 55 6e 75 73           ;# Unus
2650: 65 64 20 73 70 61 63 65 20 6f 6e 20 6c 65 61 66  ed space on leaf
2660: 20 6e 6f 64 65 73 0a 20 20 73 65 74 20 75 6e 75   nodes.  set unu
2670: 73 65 64 5f 6f 76 66 6c 20 30 20 20 20 20 20 20  sed_ovfl 0      
2680: 20 20 20 20 3b 23 20 55 6e 75 73 65 64 20 73 70      ;# Unused sp
2690: 61 63 65 20 6f 6e 20 6f 76 65 72 66 6c 6f 77 20  ace on overflow 
26a0: 70 61 67 65 73 0a 20 20 73 65 74 20 63 6e 74 5f  pages.  set cnt_
26b0: 6f 76 66 6c 20 30 20 20 20 20 20 20 20 20 20 20  ovfl 0          
26c0: 20 20 20 3b 23 20 4e 75 6d 62 65 72 20 6f 66 20     ;# Number of 
26d0: 65 6e 74 72 69 65 73 20 74 68 61 74 20 75 73 65  entries that use
26e0: 20 6f 76 65 72 66 6c 6f 77 73 0a 20 20 73 65 74   overflows.  set
26f0: 20 63 6e 74 5f 6c 65 61 66 5f 65 6e 74 72 79 20   cnt_leaf_entry 
2700: 30 20 20 20 20 20 20 20 3b 23 20 4e 75 6d 62 65  0       ;# Numbe
2710: 72 20 6f 66 20 6c 65 61 66 20 65 6e 74 72 69 65  r of leaf entrie
2720: 73 0a 20 20 73 65 74 20 6d 78 5f 70 61 79 6c 6f  s.  set mx_paylo
2730: 61 64 20 30 20 20 20 20 20 20 20 20 20 20 20 3b  ad 0           ;
2740: 23 20 4d 61 78 69 6d 75 6d 20 70 61 79 6c 6f 61  # Maximum payloa
2750: 64 20 73 69 7a 65 0a 20 20 73 65 74 20 6f 76 66  d size.  set ovf
2760: 6c 5f 70 61 67 65 73 20 30 20 20 20 20 20 20 20  l_pages 0       
2770: 20 20 20 20 3b 23 20 4e 75 6d 62 65 72 20 6f 66      ;# Number of
2780: 20 6f 76 65 72 66 6c 6f 77 20 70 61 67 65 73 20   overflow pages 
2790: 75 73 65 64 0a 20 20 73 65 74 20 6c 65 61 66 5f  used.  set leaf_
27a0: 70 61 67 65 73 20 30 20 20 20 20 20 20 20 20 20  pages 0         
27b0: 20 20 3b 23 20 4e 75 6d 62 65 72 20 6f 66 20 6c    ;# Number of l
27c0: 65 61 66 20 70 61 67 65 73 0a 0a 20 20 23 20 41  eaf pages..  # A
27d0: 73 20 74 68 65 20 62 74 72 65 65 20 69 73 20 74  s the btree is t
27e0: 72 61 76 65 72 73 65 64 2c 20 74 68 65 20 61 72  raversed, the ar
27f0: 72 61 79 20 76 61 72 69 61 62 6c 65 20 24 73 65  ray variable $se
2800: 65 6e 28 24 70 67 6e 6f 29 20 69 73 20 73 65 74  en($pgno) is set
2810: 20 74 6f 20 31 0a 20 20 23 20 74 68 65 20 66 69   to 1.  # the fi
2820: 72 73 74 20 74 69 6d 65 20 70 61 67 65 20 24 70  rst time page $p
2830: 67 6e 6f 20 69 73 20 65 6e 63 6f 75 6e 74 65 72  gno is encounter
2840: 65 64 2e 0a 20 20 23 0a 20 20 63 61 74 63 68 20  ed..  #.  catch 
2850: 7b 75 6e 73 65 74 20 73 65 65 6e 7d 0a 0a 20 20  {unset seen}..  
2860: 23 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  # The following 
2870: 6c 6f 6f 70 20 72 75 6e 73 20 6f 6e 63 65 20 66  loop runs once f
2880: 6f 72 20 65 61 63 68 20 65 6e 74 72 79 20 69 6e  or each entry in
2890: 20 69 6e 64 65 78 20 24 6e 61 6d 65 2e 20 54 68   index $name. Th
28a0: 65 20 69 6e 64 65 78 0a 20 20 23 20 69 73 20 74  e index.  # is t
28b0: 72 61 76 65 72 73 65 64 20 75 73 69 6e 67 20 74  raversed using t
28c0: 68 65 20 62 74 72 65 65 20 63 75 72 73 6f 72 20  he btree cursor 
28d0: 73 74 6f 72 65 64 20 69 6e 20 76 61 72 69 61 62  stored in variab
28e0: 6c 65 20 24 63 73 72 0a 20 20 23 0a 20 20 73 65  le $csr.  #.  se
28f0: 74 20 63 73 72 20 5b 62 74 72 65 65 5f 63 75 72  t csr [btree_cur
2900: 73 6f 72 20 24 44 42 20 24 72 6f 6f 74 70 61 67  sor $DB $rootpag
2910: 65 20 30 5d 0a 20 20 66 6f 72 20 7b 62 74 72 65  e 0].  for {btre
2920: 65 5f 66 69 72 73 74 20 24 63 73 72 7d 20 7b 21  e_first $csr} {!
2930: 5b 62 74 72 65 65 5f 65 6f 66 20 24 63 73 72 5d  [btree_eof $csr]
2940: 7d 20 7b 62 74 72 65 65 5f 6e 65 78 74 20 24 63  } {btree_next $c
2950: 73 72 7d 20 7b 0a 20 20 20 20 69 6e 63 72 20 63  sr} {.    incr c
2960: 6e 74 5f 6c 65 61 66 5f 65 6e 74 72 79 0a 0a 20  nt_leaf_entry.. 
2970: 20 20 20 23 20 52 65 74 72 69 65 76 65 20 69 6e     # Retrieve in
2980: 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20  formation about 
2990: 74 68 65 20 65 6e 74 72 79 20 74 68 65 20 62 74  the entry the bt
29a0: 72 65 65 2d 63 75 72 73 6f 72 20 70 6f 69 6e 74  ree-cursor point
29b0: 73 20 74 6f 20 69 6e 74 6f 0a 20 20 20 20 23 20  s to into.    # 
29c0: 74 68 65 20 61 72 72 61 79 20 76 61 72 69 61 62  the array variab
29d0: 6c 65 20 24 63 69 20 28 63 75 72 73 6f 72 20 69  le $ci (cursor i
29e0: 6e 66 6f 29 2e 0a 20 20 20 20 23 0a 20 20 20 20  nfo)..    #.    
29f0: 63 75 72 73 6f 72 5f 69 6e 66 6f 20 63 69 20 24  cursor_info ci $
2a00: 63 73 72 0a 0a 20 20 20 20 23 20 43 68 65 63 6b  csr..    # Check
2a10: 20 69 66 20 74 68 65 20 70 61 79 6c 6f 61 64 20   if the payload 
2a20: 6f 66 20 74 68 69 73 20 65 6e 74 72 79 20 69 73  of this entry is
2a30: 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 74 68   greater than th
2a40: 65 20 63 75 72 72 65 6e 74 20 0a 20 20 20 20 23  e current .    #
2a50: 20 24 6d 78 5f 70 61 79 6c 6f 61 64 20 73 74 61   $mx_payload sta
2a60: 74 69 73 74 69 63 20 66 6f 72 20 74 68 65 20 74  tistic for the t
2a70: 61 62 6c 65 2e 20 41 6c 73 6f 20 69 6e 63 72 65  able. Also incre
2a80: 61 73 65 20 74 68 65 20 24 74 6f 74 61 6c 5f 70  ase the $total_p
2a90: 61 79 6c 6f 61 64 0a 20 20 20 20 23 20 73 74 61  ayload.    # sta
2aa0: 74 69 73 74 69 63 2e 0a 20 20 20 20 23 0a 20 20  tistic..    #.  
2ab0: 20 20 73 65 74 20 70 61 79 6c 6f 61 64 20 5b 62    set payload [b
2ac0: 74 72 65 65 5f 6b 65 79 73 69 7a 65 20 24 63 73  tree_keysize $cs
2ad0: 72 5d 0a 20 20 20 20 69 66 20 7b 24 70 61 79 6c  r].    if {$payl
2ae0: 6f 61 64 3e 24 6d 78 5f 70 61 79 6c 6f 61 64 7d  oad>$mx_payload}
2af0: 20 7b 73 65 74 20 6d 78 5f 70 61 79 6c 6f 61 64   {set mx_payload
2b00: 20 24 70 61 79 6c 6f 61 64 7d 0a 20 20 20 20 69   $payload}.    i
2b10: 6e 63 72 20 74 6f 74 61 6c 5f 70 61 79 6c 6f 61  ncr total_payloa
2b20: 64 20 24 70 61 79 6c 6f 61 64 0a 0a 20 20 20 20  d $payload..    
2b30: 23 20 49 66 20 74 68 69 73 20 65 6e 74 72 79 20  # If this entry 
2b40: 75 73 65 73 20 6f 76 65 72 66 6c 6f 77 20 70 61  uses overflow pa
2b50: 67 65 73 2c 20 74 68 65 6e 20 75 70 64 61 74 65  ges, then update
2b60: 20 74 68 65 20 24 63 6e 74 5f 6f 76 66 6c 2c 20   the $cnt_ovfl, 
2b70: 0a 20 20 20 20 23 20 24 74 6f 74 61 6c 5f 6f 76  .    # $total_ov
2b80: 66 6c 2c 20 24 6f 76 66 6c 5f 70 61 67 65 73 20  fl, $ovfl_pages 
2b90: 61 6e 64 20 24 75 6e 75 73 65 64 5f 6f 76 66 6c  and $unused_ovfl
2ba0: 20 73 74 61 74 69 73 74 69 63 73 2e 0a 20 20 20   statistics..   
2bb0: 20 23 0a 20 20 20 20 73 65 74 20 6f 76 66 6c 20   #.    set ovfl 
2bc0: 5b 65 78 70 72 20 7b 24 70 61 79 6c 6f 61 64 2d  [expr {$payload-
2bd0: 24 63 69 28 6c 6f 63 61 6c 5f 70 61 79 6c 6f 61  $ci(local_payloa
2be0: 64 5f 62 79 74 65 73 29 7d 5d 0a 20 20 20 20 69  d_bytes)}].    i
2bf0: 66 20 7b 24 6f 76 66 6c 7d 20 7b 0a 20 20 20 20  f {$ovfl} {.    
2c00: 20 20 69 6e 63 72 20 63 6e 74 5f 6f 76 66 6c 0a    incr cnt_ovfl.
2c10: 20 20 20 20 20 20 69 6e 63 72 20 74 6f 74 61 6c        incr total
2c20: 5f 6f 76 66 6c 20 24 6f 76 66 6c 0a 20 20 20 20  _ovfl $ovfl.    
2c30: 20 20 73 65 74 20 6e 20 5b 65 78 70 72 20 7b 69    set n [expr {i
2c40: 6e 74 28 63 65 69 6c 28 24 6f 76 66 6c 2f 28 24  nt(ceil($ovfl/($
2c50: 70 61 67 65 53 69 7a 65 2d 34 2e 30 29 29 29 7d  pageSize-4.0)))}
2c60: 5d 0a 20 20 20 20 20 20 69 6e 63 72 20 6f 76 66  ].      incr ovf
2c70: 6c 5f 70 61 67 65 73 20 24 6e 0a 20 20 20 20 20  l_pages $n.     
2c80: 20 69 6e 63 72 20 75 6e 75 73 65 64 5f 6f 76 66   incr unused_ovf
2c90: 6c 20 5b 65 78 70 72 20 7b 24 6e 2a 28 24 70 61  l [expr {$n*($pa
2ca0: 67 65 53 69 7a 65 2d 34 29 20 2d 20 24 6f 76 66  geSize-4) - $ovf
2cb0: 6c 7d 5d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 23  l}].    }..    #
2cc0: 20 49 66 20 74 68 69 73 20 69 73 20 74 68 65 20   If this is the 
2cd0: 66 69 72 73 74 20 74 61 62 6c 65 20 65 6e 74 72  first table entr
2ce0: 79 20 61 6e 61 6c 79 7a 65 64 20 66 6f 72 20 74  y analyzed for t
2cf0: 68 65 20 70 61 67 65 2c 20 74 68 65 6e 20 75 70  he page, then up
2d00: 64 61 74 65 0a 20 20 20 20 23 20 74 68 65 20 70  date.    # the p
2d10: 61 67 65 2d 72 65 6c 61 74 65 64 20 73 74 61 74  age-related stat
2d20: 69 73 74 69 63 73 20 24 6c 65 61 66 5f 70 61 67  istics $leaf_pag
2d30: 65 73 20 61 6e 64 20 24 75 6e 75 73 65 64 5f 6c  es and $unused_l
2d40: 65 61 66 2e 0a 20 20 20 20 23 0a 20 20 20 20 69  eaf..    #.    i
2d50: 66 20 7b 21 5b 69 6e 66 6f 20 65 78 69 73 74 73  f {![info exists
2d60: 20 73 65 65 6e 28 24 63 69 28 70 61 67 65 5f 6e   seen($ci(page_n
2d70: 6f 29 29 5d 7d 20 7b 0a 20 20 20 20 20 20 73 65  o))]} {.      se
2d80: 74 20 73 65 65 6e 28 24 63 69 28 70 61 67 65 5f  t seen($ci(page_
2d90: 6e 6f 29 29 20 31 0a 20 20 20 20 20 20 69 6e 63  no)) 1.      inc
2da0: 72 20 6c 65 61 66 5f 70 61 67 65 73 0a 20 20 20  r leaf_pages.   
2db0: 20 20 20 69 6e 63 72 20 75 6e 75 73 65 64 5f 6c     incr unused_l
2dc0: 65 61 66 20 24 63 69 28 70 61 67 65 5f 66 72 65  eaf $ci(page_fre
2dd0: 65 62 79 74 65 73 29 0a 20 20 20 20 7d 0a 20 20  ebytes).    }.  
2de0: 7d 0a 20 20 62 74 72 65 65 5f 63 6c 6f 73 65 5f  }.  btree_close_
2df0: 63 75 72 73 6f 72 20 24 63 73 72 0a 0a 20 20 23  cursor $csr..  #
2e00: 20 48 61 6e 64 6c 65 20 74 68 65 20 73 70 65 63   Handle the spec
2e10: 69 61 6c 20 63 61 73 65 20 77 68 65 72 65 20 61  ial case where a
2e20: 20 69 6e 64 65 78 20 63 6f 6e 74 61 69 6e 73 20   index contains 
2e30: 6e 6f 20 64 61 74 61 2e 20 49 6e 20 74 68 69 73  no data. In this
2e40: 20 63 61 73 65 0a 20 20 23 20 61 6c 6c 20 73 74   case.  # all st
2e50: 61 74 69 73 74 69 63 73 20 61 72 65 20 7a 65 72  atistics are zer
2e60: 6f 2c 20 65 78 63 65 70 74 20 66 6f 72 20 74 68  o, except for th
2e70: 65 20 6e 75 6d 62 65 72 20 6f 66 20 6c 65 61 66  e number of leaf
2e80: 20 70 61 67 65 73 20 28 31 29 20 61 6e 64 0a 20   pages (1) and. 
2e90: 20 23 20 74 68 65 20 75 6e 75 73 65 64 20 62 79   # the unused by
2ea0: 74 65 73 20 6f 6e 20 6c 65 61 66 20 70 61 67 65  tes on leaf page
2eb0: 73 20 28 24 70 61 67 65 53 69 7a 65 20 2d 20 38  s ($pageSize - 8
2ec0: 29 2e 0a 20 20 23 0a 20 20 69 66 20 7b 5b 6c 6c  )..  #.  if {[ll
2ed0: 65 6e 67 74 68 20 5b 61 72 72 61 79 20 6e 61 6d  ength [array nam
2ee0: 65 73 20 73 65 65 6e 5d 5d 3d 3d 30 7d 20 7b 0a  es seen]]==0} {.
2ef0: 20 20 20 20 73 65 74 20 6c 65 61 66 5f 70 61 67      set leaf_pag
2f00: 65 73 20 31 0a 20 20 20 20 73 65 74 20 75 6e 75  es 1.    set unu
2f10: 73 65 64 5f 6c 65 61 66 20 5b 65 78 70 72 20 7b  sed_leaf [expr {
2f20: 24 70 61 67 65 53 69 7a 65 2d 38 7d 5d 0a 20 20  $pageSize-8}].  
2f30: 7d 0a 0a 20 20 23 20 49 6e 73 65 72 74 20 74 68  }..  # Insert th
2f40: 65 20 73 74 61 74 69 73 74 69 63 73 20 66 6f 72  e statistics for
2f50: 20 74 68 65 20 69 6e 64 65 78 20 61 6e 61 6c 79   the index analy
2f60: 7a 65 64 20 69 6e 74 6f 20 74 68 65 20 69 6e 2d  zed into the in-
2f70: 6d 65 6d 6f 72 79 20 64 61 74 61 62 61 73 65 2e  memory database.
2f80: 0a 20 20 23 0a 20 20 73 65 74 20 73 71 6c 20 22  .  #.  set sql "
2f90: 49 4e 53 45 52 54 20 49 4e 54 4f 20 73 70 61 63  INSERT INTO spac
2fa0: 65 5f 75 73 65 64 20 56 41 4c 55 45 53 28 22 0a  e_used VALUES(".
2fb0: 20 20 61 70 70 65 6e 64 20 73 71 6c 20 5b 71 75    append sql [qu
2fc0: 6f 74 65 20 24 6e 61 6d 65 5d 0a 20 20 61 70 70  ote $name].  app
2fd0: 65 6e 64 20 73 71 6c 20 22 2c 5b 71 75 6f 74 65  end sql ",[quote
2fe0: 20 24 74 62 6c 5f 6e 61 6d 65 5d 22 0a 20 20 61   $tbl_name]".  a
2ff0: 70 70 65 6e 64 20 73 71 6c 20 22 2c 31 22 0a 20  ppend sql ",1". 
3000: 20 61 70 70 65 6e 64 20 73 71 6c 20 22 2c 24 63   append sql ",$c
3010: 6e 74 5f 6c 65 61 66 5f 65 6e 74 72 79 22 0a 20  nt_leaf_entry". 
3020: 20 61 70 70 65 6e 64 20 73 71 6c 20 22 2c 24 63   append sql ",$c
3030: 6e 74 5f 6c 65 61 66 5f 65 6e 74 72 79 22 0a 20  nt_leaf_entry". 
3040: 20 61 70 70 65 6e 64 20 73 71 6c 20 22 2c 24 74   append sql ",$t
3050: 6f 74 61 6c 5f 70 61 79 6c 6f 61 64 22 0a 20 20  otal_payload".  
3060: 61 70 70 65 6e 64 20 73 71 6c 20 22 2c 24 74 6f  append sql ",$to
3070: 74 61 6c 5f 6f 76 66 6c 22 0a 20 20 61 70 70 65  tal_ovfl".  appe
3080: 6e 64 20 73 71 6c 20 22 2c 24 63 6e 74 5f 6f 76  nd sql ",$cnt_ov
3090: 66 6c 22 0a 20 20 61 70 70 65 6e 64 20 73 71 6c  fl".  append sql
30a0: 20 22 2c 24 6d 78 5f 70 61 79 6c 6f 61 64 22 0a   ",$mx_payload".
30b0: 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22 2c 30    append sql ",0
30c0: 22 0a 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22  ".  append sql "
30d0: 2c 24 6c 65 61 66 5f 70 61 67 65 73 22 0a 20 20  ,$leaf_pages".  
30e0: 61 70 70 65 6e 64 20 73 71 6c 20 22 2c 24 6f 76  append sql ",$ov
30f0: 66 6c 5f 70 61 67 65 73 22 0a 20 20 61 70 70 65  fl_pages".  appe
3100: 6e 64 20 73 71 6c 20 22 2c 30 22 0a 20 20 61 70  nd sql ",0".  ap
3110: 70 65 6e 64 20 73 71 6c 20 22 2c 24 75 6e 75 73  pend sql ",$unus
3120: 65 64 5f 6c 65 61 66 22 0a 20 20 61 70 70 65 6e  ed_leaf".  appen
3130: 64 20 73 71 6c 20 22 2c 24 75 6e 75 73 65 64 5f  d sql ",$unused_
3140: 6f 76 66 6c 22 0a 20 20 61 70 70 65 6e 64 20 73  ovfl".  append s
3150: 71 6c 20 29 3b 0a 20 20 6d 65 6d 20 65 76 61 6c  ql );.  mem eval
3160: 20 24 73 71 6c 0a 7d 0a 0a 23 20 47 65 6e 65 72   $sql.}..# Gener
3170: 61 74 65 20 61 20 73 69 6e 67 6c 65 20 6c 69 6e  ate a single lin
3180: 65 20 6f 66 20 6f 75 74 70 75 74 20 69 6e 20 74  e of output in t
3190: 68 65 20 73 74 61 74 69 73 74 69 63 73 20 73 65  he statistics se
31a0: 63 74 69 6f 6e 20 6f 66 20 74 68 65 0a 23 20 72  ction of the.# r
31b0: 65 70 6f 72 74 2e 0a 23 0a 70 72 6f 63 20 73 74  eport..#.proc st
31c0: 61 74 6c 69 6e 65 20 7b 74 69 74 6c 65 20 76 61  atline {title va
31d0: 6c 75 65 20 7b 65 78 74 72 61 20 7b 7d 7d 7d 20  lue {extra {}}} 
31e0: 7b 0a 20 20 73 65 74 20 6c 65 6e 20 5b 73 74 72  {.  set len [str
31f0: 69 6e 67 20 6c 65 6e 67 74 68 20 24 74 69 74 6c  ing length $titl
3200: 65 5d 0a 20 20 73 65 74 20 64 6f 74 73 20 5b 73  e].  set dots [s
3210: 74 72 69 6e 67 20 72 61 6e 67 65 20 7b 2e 2e 2e  tring range {...
3220: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e  ................
3230: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e  ................
3240: 2e 2e 2e 7d 20 24 6c 65 6e 20 65 6e 64 5d 0a 20  ...} $len end]. 
3250: 20 73 65 74 20 6c 65 6e 20 5b 73 74 72 69 6e 67   set len [string
3260: 20 6c 65 6e 67 74 68 20 24 76 61 6c 75 65 5d 0a   length $value].
3270: 20 20 73 65 74 20 73 70 32 20 5b 73 74 72 69 6e    set sp2 [strin
3280: 67 20 72 61 6e 67 65 20 7b 20 20 20 20 20 20 20  g range {       
3290: 20 20 20 7d 20 24 6c 65 6e 20 65 6e 64 5d 0a 20     } $len end]. 
32a0: 20 69 66 20 7b 24 65 78 74 72 61 20 6e 65 20 22   if {$extra ne "
32b0: 22 7d 20 7b 0a 20 20 20 20 73 65 74 20 65 78 74  "} {.    set ext
32c0: 72 61 20 22 20 24 65 78 74 72 61 22 0a 20 20 7d  ra " $extra".  }
32d0: 0a 20 20 70 75 74 73 20 22 24 74 69 74 6c 65 24  .  puts "$title$
32e0: 64 6f 74 73 20 24 76 61 6c 75 65 24 73 70 32 24  dots $value$sp2$
32f0: 65 78 74 72 61 22 0a 7d 0a 0a 23 20 47 65 6e 65  extra".}..# Gene
3300: 72 61 74 65 20 61 20 66 6f 72 6d 61 74 74 65 64  rate a formatted
3310: 20 70 65 72 63 65 6e 74 61 67 65 20 76 61 6c 75   percentage valu
3320: 65 20 66 6f 72 20 24 6e 75 6d 2f 24 64 65 6e 6f  e for $num/$deno
3330: 6d 0a 23 0a 70 72 6f 63 20 70 65 72 63 65 6e 74  m.#.proc percent
3340: 20 7b 6e 75 6d 20 64 65 6e 6f 6d 20 7b 6f 66 20   {num denom {of 
3350: 7b 7d 7d 7d 20 7b 0a 20 20 69 66 20 7b 24 64 65  {}}} {.  if {$de
3360: 6e 6f 6d 3d 3d 30 2e 30 7d 20 7b 72 65 74 75 72  nom==0.0} {retur
3370: 6e 20 22 22 7d 0a 20 20 73 65 74 20 76 20 5b 65  n ""}.  set v [e
3380: 78 70 72 20 7b 24 6e 75 6d 2a 31 30 30 2e 30 2f  xpr {$num*100.0/
3390: 24 64 65 6e 6f 6d 7d 5d 0a 20 20 73 65 74 20 6f  $denom}].  set o
33a0: 66 20 7b 7d 0a 20 20 69 66 20 7b 24 76 3d 3d 31  f {}.  if {$v==1
33b0: 30 30 2e 30 20 7c 7c 20 24 76 3c 30 2e 30 30 31  00.0 || $v<0.001
33c0: 20 7c 7c 20 28 24 76 3e 31 2e 30 20 26 26 20 24   || ($v>1.0 && $
33d0: 76 3c 39 39 2e 30 29 7d 20 7b 0a 20 20 20 20 72  v<99.0)} {.    r
33e0: 65 74 75 72 6e 20 5b 66 6f 72 6d 61 74 20 7b 25  eturn [format {%
33f0: 35 2e 31 66 25 25 20 25 73 7d 20 24 76 20 24 6f  5.1f%% %s} $v $o
3400: 66 5d 0a 20 20 7d 20 65 6c 73 65 69 66 20 7b 24  f].  } elseif {$
3410: 76 3c 30 2e 31 20 7c 7c 20 24 76 3e 39 39 2e 39  v<0.1 || $v>99.9
3420: 7d 20 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 5b  } {.    return [
3430: 66 6f 72 6d 61 74 20 7b 25 37 2e 33 66 25 25 20  format {%7.3f%% 
3440: 25 73 7d 20 24 76 20 24 6f 66 5d 0a 20 20 7d 20  %s} $v $of].  } 
3450: 65 6c 73 65 20 7b 0a 20 20 20 20 72 65 74 75 72  else {.    retur
3460: 6e 20 5b 66 6f 72 6d 61 74 20 7b 25 36 2e 32 66  n [format {%6.2f
3470: 25 25 20 25 73 7d 20 24 76 20 24 6f 66 5d 0a 20  %% %s} $v $of]. 
3480: 20 7d 0a 7d 0a 0a 70 72 6f 63 20 64 69 76 69 64   }.}..proc divid
3490: 65 20 7b 6e 75 6d 20 64 65 6e 6f 6d 7d 20 7b 0a  e {num denom} {.
34a0: 20 20 69 66 20 7b 24 64 65 6e 6f 6d 3d 3d 30 7d    if {$denom==0}
34b0: 20 7b 72 65 74 75 72 6e 20 30 2e 30 7d 0a 20 20   {return 0.0}.  
34c0: 72 65 74 75 72 6e 20 5b 66 6f 72 6d 61 74 20 25  return [format %
34d0: 2e 32 66 20 5b 65 78 70 72 20 64 6f 75 62 6c 65  .2f [expr double
34e0: 28 24 6e 75 6d 29 2f 64 6f 75 62 6c 65 28 24 64  ($num)/double($d
34f0: 65 6e 6f 6d 29 5d 5d 0a 7d 0a 0a 23 20 47 65 6e  enom)]].}..# Gen
3500: 65 72 61 74 65 20 61 20 73 75 62 72 65 70 6f 72  erate a subrepor
3510: 74 20 74 68 61 74 20 63 6f 76 65 72 73 20 73 6f  t that covers so
3520: 6d 65 20 73 75 62 73 65 74 20 6f 66 20 74 68 65  me subset of the
3530: 20 64 61 74 61 62 61 73 65 2e 0a 23 20 74 68 65   database..# the
3540: 20 24 77 68 65 72 65 20 63 6c 61 75 73 65 20 64   $where clause d
3550: 65 74 65 72 6d 69 6e 65 73 20 77 68 69 63 68 20  etermines which 
3560: 73 75 62 73 65 74 20 74 6f 20 61 6e 61 6c 79 7a  subset to analyz
3570: 65 2e 0a 23 0a 70 72 6f 63 20 73 75 62 72 65 70  e..#.proc subrep
3580: 6f 72 74 20 7b 74 69 74 6c 65 20 77 68 65 72 65  ort {title where
3590: 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c 20 70 61 67  } {.  global pag
35a0: 65 53 69 7a 65 20 66 69 6c 65 5f 70 67 63 6e 74  eSize file_pgcnt
35b0: 0a 0a 20 20 23 20 51 75 65 72 79 20 74 68 65 20  ..  # Query the 
35c0: 69 6e 2d 6d 65 6d 6f 72 79 20 64 61 74 61 62 61  in-memory databa
35d0: 73 65 20 66 6f 72 20 74 68 65 20 73 75 6d 20 6f  se for the sum o
35e0: 66 20 76 61 72 69 6f 75 73 20 73 74 61 74 69 73  f various statis
35f0: 74 69 63 73 20 0a 20 20 23 20 66 6f 72 20 74 68  tics .  # for th
3600: 65 20 73 75 62 73 65 74 20 6f 66 20 74 61 62 6c  e subset of tabl
3610: 65 73 2f 69 6e 64 69 63 65 73 20 69 64 65 6e 74  es/indices ident
3620: 69 66 69 65 64 20 62 79 20 74 68 65 20 57 48 45  ified by the WHE
3630: 52 45 20 63 6c 61 75 73 65 20 69 6e 0a 20 20 23  RE clause in.  #
3640: 20 24 77 68 65 72 65 2e 20 4e 6f 74 65 20 74 68   $where. Note th
3650: 61 74 20 65 76 65 6e 20 69 66 20 74 68 65 20 57  at even if the W
3660: 48 45 52 45 20 63 6c 61 75 73 65 20 6d 61 74 63  HERE clause matc
3670: 68 65 73 20 6e 6f 20 72 6f 77 73 2c 20 74 68 65  hes no rows, the
3680: 0a 20 20 23 20 66 6f 6c 6c 6f 77 69 6e 67 20 71  .  # following q
3690: 75 65 72 79 20 72 65 74 75 72 6e 73 20 65 78 61  uery returns exa
36a0: 63 74 6c 79 20 6f 6e 65 20 72 6f 77 20 28 62 65  ctly one row (be
36b0: 63 61 75 73 65 20 69 74 20 69 73 20 61 6e 20 61  cause it is an a
36c0: 67 67 72 65 67 61 74 65 29 2e 0a 20 20 23 0a 20  ggregate)..  #. 
36d0: 20 23 20 54 68 65 20 72 65 73 75 6c 74 73 20 6f   # The results o
36e0: 66 20 74 68 65 20 71 75 65 72 79 20 61 72 65 20  f the query are 
36f0: 73 74 6f 72 65 64 20 64 69 72 65 63 74 6c 79 20  stored directly 
3700: 62 79 20 53 51 4c 69 74 65 20 69 6e 74 6f 20 6c  by SQLite into l
3710: 6f 63 61 6c 20 0a 20 20 23 20 76 61 72 69 61 62  ocal .  # variab
3720: 6c 65 73 20 28 69 2e 65 2e 20 24 6e 65 6e 74 72  les (i.e. $nentr
3730: 79 2c 20 24 6e 6c 65 61 66 20 65 74 63 2e 29 2e  y, $nleaf etc.).
3740: 0a 20 20 23 0a 20 20 6d 65 6d 20 65 76 61 6c 20  .  #.  mem eval 
3750: 22 0a 20 20 20 20 53 45 4c 45 43 54 0a 20 20 20  ".    SELECT.   
3760: 20 20 20 69 6e 74 28 73 75 6d 28 6e 65 6e 74 72     int(sum(nentr
3770: 79 29 29 20 41 53 20 6e 65 6e 74 72 79 2c 0a 20  y)) AS nentry,. 
3780: 20 20 20 20 20 69 6e 74 28 73 75 6d 28 6c 65 61       int(sum(lea
3790: 66 5f 65 6e 74 72 69 65 73 29 29 20 41 53 20 6e  f_entries)) AS n
37a0: 6c 65 61 66 2c 0a 20 20 20 20 20 20 69 6e 74 28  leaf,.      int(
37b0: 73 75 6d 28 70 61 79 6c 6f 61 64 29 29 20 41 53  sum(payload)) AS
37c0: 20 70 61 79 6c 6f 61 64 2c 0a 20 20 20 20 20 20   payload,.      
37d0: 69 6e 74 28 73 75 6d 28 6f 76 66 6c 5f 70 61 79  int(sum(ovfl_pay
37e0: 6c 6f 61 64 29 29 20 41 53 20 6f 76 66 6c 5f 70  load)) AS ovfl_p
37f0: 61 79 6c 6f 61 64 2c 0a 20 20 20 20 20 20 6d 61  ayload,.      ma
3800: 78 28 6d 78 5f 70 61 79 6c 6f 61 64 29 20 41 53  x(mx_payload) AS
3810: 20 6d 78 5f 70 61 79 6c 6f 61 64 2c 0a 20 20 20   mx_payload,.   
3820: 20 20 20 69 6e 74 28 73 75 6d 28 6f 76 66 6c 5f     int(sum(ovfl_
3830: 63 6e 74 29 29 20 61 73 20 6f 76 66 6c 5f 63 6e  cnt)) as ovfl_cn
3840: 74 2c 0a 20 20 20 20 20 20 69 6e 74 28 73 75 6d  t,.      int(sum
3850: 28 6c 65 61 66 5f 70 61 67 65 73 29 29 20 41 53  (leaf_pages)) AS
3860: 20 6c 65 61 66 5f 70 61 67 65 73 2c 0a 20 20 20   leaf_pages,.   
3870: 20 20 20 69 6e 74 28 73 75 6d 28 69 6e 74 5f 70     int(sum(int_p
3880: 61 67 65 73 29 29 20 41 53 20 69 6e 74 5f 70 61  ages)) AS int_pa
3890: 67 65 73 2c 0a 20 20 20 20 20 20 69 6e 74 28 73  ges,.      int(s
38a0: 75 6d 28 6f 76 66 6c 5f 70 61 67 65 73 29 29 20  um(ovfl_pages)) 
38b0: 41 53 20 6f 76 66 6c 5f 70 61 67 65 73 2c 0a 20  AS ovfl_pages,. 
38c0: 20 20 20 20 20 69 6e 74 28 73 75 6d 28 6c 65 61       int(sum(lea
38d0: 66 5f 75 6e 75 73 65 64 29 29 20 41 53 20 6c 65  f_unused)) AS le
38e0: 61 66 5f 75 6e 75 73 65 64 2c 0a 20 20 20 20 20  af_unused,.     
38f0: 20 69 6e 74 28 73 75 6d 28 69 6e 74 5f 75 6e 75   int(sum(int_unu
3900: 73 65 64 29 29 20 41 53 20 69 6e 74 5f 75 6e 75  sed)) AS int_unu
3910: 73 65 64 2c 0a 20 20 20 20 20 20 69 6e 74 28 73  sed,.      int(s
3920: 75 6d 28 6f 76 66 6c 5f 75 6e 75 73 65 64 29 29  um(ovfl_unused))
3930: 20 41 53 20 6f 76 66 6c 5f 75 6e 75 73 65 64 0a   AS ovfl_unused.
3940: 20 20 20 20 46 52 4f 4d 20 73 70 61 63 65 5f 75      FROM space_u
3950: 73 65 64 20 57 48 45 52 45 20 24 77 68 65 72 65  sed WHERE $where
3960: 22 20 7b 7d 20 7b 7d 0a 0a 20 20 23 20 4f 75 74  " {} {}..  # Out
3970: 70 75 74 20 74 68 65 20 73 75 62 2d 72 65 70 6f  put the sub-repo
3980: 72 74 20 74 69 74 6c 65 2c 20 6e 69 63 65 6c 79  rt title, nicely
3990: 20 64 65 63 6f 72 61 74 65 64 20 77 69 74 68 20   decorated with 
39a0: 2a 20 63 68 61 72 61 63 74 65 72 73 2e 0a 20 20  * characters..  
39b0: 23 0a 20 20 70 75 74 73 20 22 22 0a 20 20 73 65  #.  puts "".  se
39c0: 74 20 6c 65 6e 20 5b 73 74 72 69 6e 67 20 6c 65  t len [string le
39d0: 6e 67 74 68 20 24 74 69 74 6c 65 5d 0a 20 20 73  ngth $title].  s
39e0: 65 74 20 73 74 61 72 73 20 5b 73 74 72 69 6e 67  et stars [string
39f0: 20 72 65 70 65 61 74 20 2a 20 5b 65 78 70 72 20   repeat * [expr 
3a00: 36 35 2d 24 6c 65 6e 5d 5d 0a 20 20 70 75 74 73  65-$len]].  puts
3a10: 20 22 2a 2a 2a 20 24 74 69 74 6c 65 20 24 73 74   "*** $title $st
3a20: 61 72 73 22 0a 20 20 70 75 74 73 20 22 22 0a 0a  ars".  puts ""..
3a30: 20 20 23 20 43 61 6c 63 75 6c 61 74 65 20 73 74    # Calculate st
3a40: 61 74 69 73 74 69 63 73 20 61 6e 64 20 73 74 6f  atistics and sto
3a50: 72 65 20 74 68 65 20 72 65 73 75 6c 74 73 20 69  re the results i
3a60: 6e 20 54 43 4c 20 76 61 72 69 61 62 6c 65 73 2c  n TCL variables,
3a70: 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 20 20 23   as follows:.  #
3a80: 0a 20 20 23 20 74 6f 74 61 6c 5f 70 61 67 65 73  .  # total_pages
3a90: 3a 20 44 61 74 61 62 61 73 65 20 70 61 67 65 73  : Database pages
3aa0: 20 63 6f 6e 73 75 6d 65 64 2e 0a 20 20 23 20 74   consumed..  # t
3ab0: 6f 74 61 6c 5f 70 61 67 65 73 5f 70 65 72 63 65  otal_pages_perce
3ac0: 6e 74 3a 20 50 61 67 65 73 20 63 6f 6e 73 75 6d  nt: Pages consum
3ad0: 65 64 20 61 73 20 61 20 70 65 72 63 65 6e 74 61  ed as a percenta
3ae0: 67 65 20 6f 66 20 74 68 65 20 66 69 6c 65 2e 0a  ge of the file..
3af0: 20 20 23 20 73 74 6f 72 61 67 65 3a 20 42 79 74    # storage: Byt
3b00: 65 73 20 63 6f 6e 73 75 6d 65 64 2e 0a 20 20 23  es consumed..  #
3b10: 20 70 61 79 6c 6f 61 64 5f 70 65 72 63 65 6e 74   payload_percent
3b20: 3a 20 50 61 79 6c 6f 61 64 20 62 79 74 65 73 20  : Payload bytes 
3b30: 75 73 65 64 20 61 73 20 61 20 70 65 72 63 65 6e  used as a percen
3b40: 74 61 67 65 20 6f 66 20 24 73 74 6f 72 61 67 65  tage of $storage
3b50: 2e 0a 20 20 23 20 74 6f 74 61 6c 5f 75 6e 75 73  ..  # total_unus
3b60: 65 64 3a 20 55 6e 75 73 65 64 20 62 79 74 65 73  ed: Unused bytes
3b70: 20 6f 6e 20 70 61 67 65 73 2e 0a 20 20 23 20 61   on pages..  # a
3b80: 76 67 5f 70 61 79 6c 6f 61 64 3a 20 41 76 65 72  vg_payload: Aver
3b90: 61 67 65 20 70 61 79 6c 6f 61 64 20 70 65 72 20  age payload per 
3ba0: 62 74 72 65 65 20 65 6e 74 72 79 2e 0a 20 20 23  btree entry..  #
3bb0: 20 61 76 67 5f 66 61 6e 6f 75 74 3a 20 41 76 65   avg_fanout: Ave
3bc0: 72 61 67 65 20 66 61 6e 6f 75 74 20 66 6f 72 20  rage fanout for 
3bd0: 69 6e 74 65 72 6e 61 6c 20 70 61 67 65 73 2e 0a  internal pages..
3be0: 20 20 23 20 61 76 67 5f 75 6e 75 73 65 64 3a 20    # avg_unused: 
3bf0: 41 76 65 72 61 67 65 20 75 6e 75 73 65 64 20 62  Average unused b
3c00: 79 74 65 73 20 70 65 72 20 62 74 72 65 65 20 65  ytes per btree e
3c10: 6e 74 72 79 2e 0a 20 20 23 20 6f 76 66 6c 5f 63  ntry..  # ovfl_c
3c20: 6e 74 5f 70 65 72 63 65 6e 74 3a 20 50 65 72 63  nt_percent: Perc
3c30: 65 6e 74 61 67 65 20 6f 66 20 62 74 72 65 65 20  entage of btree 
3c40: 65 6e 74 72 69 65 73 20 74 68 61 74 20 75 73 65  entries that use
3c50: 20 6f 76 65 72 66 6c 6f 77 20 70 61 67 65 73 2e   overflow pages.
3c60: 0a 20 20 23 0a 20 20 73 65 74 20 74 6f 74 61 6c  .  #.  set total
3c70: 5f 70 61 67 65 73 20 5b 65 78 70 72 20 7b 24 6c  _pages [expr {$l
3c80: 65 61 66 5f 70 61 67 65 73 2b 24 69 6e 74 5f 70  eaf_pages+$int_p
3c90: 61 67 65 73 2b 24 6f 76 66 6c 5f 70 61 67 65 73  ages+$ovfl_pages
3ca0: 7d 5d 0a 20 20 73 65 74 20 74 6f 74 61 6c 5f 70  }].  set total_p
3cb0: 61 67 65 73 5f 70 65 72 63 65 6e 74 20 5b 70 65  ages_percent [pe
3cc0: 72 63 65 6e 74 20 24 74 6f 74 61 6c 5f 70 61 67  rcent $total_pag
3cd0: 65 73 20 24 66 69 6c 65 5f 70 67 63 6e 74 5d 0a  es $file_pgcnt].
3ce0: 20 20 73 65 74 20 73 74 6f 72 61 67 65 20 5b 65    set storage [e
3cf0: 78 70 72 20 7b 24 74 6f 74 61 6c 5f 70 61 67 65  xpr {$total_page
3d00: 73 2a 24 70 61 67 65 53 69 7a 65 7d 5d 0a 20 20  s*$pageSize}].  
3d10: 73 65 74 20 70 61 79 6c 6f 61 64 5f 70 65 72 63  set payload_perc
3d20: 65 6e 74 20 5b 70 65 72 63 65 6e 74 20 24 70 61  ent [percent $pa
3d30: 79 6c 6f 61 64 20 24 73 74 6f 72 61 67 65 20 7b  yload $storage {
3d40: 6f 66 20 73 74 6f 72 61 67 65 20 63 6f 6e 73 75  of storage consu
3d50: 6d 65 64 7d 5d 0a 20 20 73 65 74 20 74 6f 74 61  med}].  set tota
3d60: 6c 5f 75 6e 75 73 65 64 20 5b 65 78 70 72 20 7b  l_unused [expr {
3d70: 24 6f 76 66 6c 5f 75 6e 75 73 65 64 2b 24 69 6e  $ovfl_unused+$in
3d80: 74 5f 75 6e 75 73 65 64 2b 24 6c 65 61 66 5f 75  t_unused+$leaf_u
3d90: 6e 75 73 65 64 7d 5d 0a 20 20 73 65 74 20 61 76  nused}].  set av
3da0: 67 5f 70 61 79 6c 6f 61 64 20 5b 64 69 76 69 64  g_payload [divid
3db0: 65 20 24 70 61 79 6c 6f 61 64 20 24 6e 6c 65 61  e $payload $nlea
3dc0: 66 5d 0a 20 20 73 65 74 20 61 76 67 5f 75 6e 75  f].  set avg_unu
3dd0: 73 65 64 20 5b 64 69 76 69 64 65 20 24 74 6f 74  sed [divide $tot
3de0: 61 6c 5f 75 6e 75 73 65 64 20 24 6e 6c 65 61 66  al_unused $nleaf
3df0: 5d 0a 20 20 69 66 20 7b 24 69 6e 74 5f 70 61 67  ].  if {$int_pag
3e00: 65 73 3e 30 7d 20 7b 0a 20 20 20 20 23 20 54 4f  es>0} {.    # TO
3e10: 44 4f 3a 20 49 73 20 74 68 69 73 20 66 6f 72 6d  DO: Is this form
3e20: 75 6c 61 20 63 6f 72 72 65 63 74 3f 0a 20 20 20  ula correct?.   
3e30: 20 73 65 74 20 6e 54 61 62 20 5b 6d 65 6d 20 65   set nTab [mem e
3e40: 76 61 6c 20 22 0a 20 20 20 20 20 20 53 45 4c 45  val ".      SELE
3e50: 43 54 20 63 6f 75 6e 74 28 2a 29 20 46 52 4f 4d  CT count(*) FROM
3e60: 20 28 0a 20 20 20 20 20 20 20 20 20 20 53 45 4c   (.          SEL
3e70: 45 43 54 20 44 49 53 54 49 4e 43 54 20 74 62 6c  ECT DISTINCT tbl
3e80: 6e 61 6d 65 20 46 52 4f 4d 20 73 70 61 63 65 5f  name FROM space_
3e90: 75 73 65 64 20 57 48 45 52 45 20 24 77 68 65 72  used WHERE $wher
3ea0: 65 20 41 4e 44 20 69 73 5f 69 6e 64 65 78 3d 30  e AND is_index=0
3eb0: 0a 20 20 20 20 20 20 29 0a 20 20 20 20 22 5d 0a  .      ).    "].
3ec0: 20 20 20 20 73 65 74 20 61 76 67 5f 66 61 6e 6f      set avg_fano
3ed0: 75 74 20 5b 6d 65 6d 20 65 76 61 6c 20 22 0a 20  ut [mem eval ". 
3ee0: 20 20 20 20 20 53 45 4c 45 43 54 20 28 73 75 6d       SELECT (sum
3ef0: 28 6c 65 61 66 5f 70 61 67 65 73 2b 69 6e 74 5f  (leaf_pages+int_
3f00: 70 61 67 65 73 29 2d 24 6e 54 61 62 29 2f 73 75  pages)-$nTab)/su
3f10: 6d 28 69 6e 74 5f 70 61 67 65 73 29 20 46 52 4f  m(int_pages) FRO
3f20: 4d 20 73 70 61 63 65 5f 75 73 65 64 0a 20 20 20  M space_used.   
3f30: 20 20 20 20 20 20 20 57 48 45 52 45 20 24 77 68         WHERE $wh
3f40: 65 72 65 20 41 4e 44 20 69 73 5f 69 6e 64 65 78  ere AND is_index
3f50: 20 3d 20 30 0a 20 20 20 20 22 5d 0a 20 20 20 20   = 0.    "].    
3f60: 73 65 74 20 61 76 67 5f 66 61 6e 6f 75 74 20 5b  set avg_fanout [
3f70: 66 6f 72 6d 61 74 20 25 2e 32 66 20 24 61 76 67  format %.2f $avg
3f80: 5f 66 61 6e 6f 75 74 5d 0a 20 20 7d 0a 20 20 73  _fanout].  }.  s
3f90: 65 74 20 6f 76 66 6c 5f 63 6e 74 5f 70 65 72 63  et ovfl_cnt_perc
3fa0: 65 6e 74 20 5b 70 65 72 63 65 6e 74 20 24 6f 76  ent [percent $ov
3fb0: 66 6c 5f 63 6e 74 20 24 6e 6c 65 61 66 20 7b 6f  fl_cnt $nleaf {o
3fc0: 66 20 61 6c 6c 20 65 6e 74 72 69 65 73 7d 5d 0a  f all entries}].
3fd0: 0a 20 20 23 20 50 72 69 6e 74 20 6f 75 74 20 74  .  # Print out t
3fe0: 68 65 20 73 75 62 2d 72 65 70 6f 72 74 20 73 74  he sub-report st
3ff0: 61 74 69 73 74 69 63 73 2e 0a 20 20 23 0a 20 20  atistics..  #.  
4000: 73 74 61 74 6c 69 6e 65 20 7b 50 65 72 63 65 6e  statline {Percen
4010: 74 61 67 65 20 6f 66 20 74 6f 74 61 6c 20 64 61  tage of total da
4020: 74 61 62 61 73 65 7d 20 24 74 6f 74 61 6c 5f 70  tabase} $total_p
4030: 61 67 65 73 5f 70 65 72 63 65 6e 74 0a 20 20 73  ages_percent.  s
4040: 74 61 74 6c 69 6e 65 20 7b 4e 75 6d 62 65 72 20  tatline {Number 
4050: 6f 66 20 65 6e 74 72 69 65 73 7d 20 24 6e 6c 65  of entries} $nle
4060: 61 66 0a 20 20 73 74 61 74 6c 69 6e 65 20 7b 42  af.  statline {B
4070: 79 74 65 73 20 6f 66 20 73 74 6f 72 61 67 65 20  ytes of storage 
4080: 63 6f 6e 73 75 6d 65 64 7d 20 24 73 74 6f 72 61  consumed} $stora
4090: 67 65 0a 20 20 73 74 61 74 6c 69 6e 65 20 7b 42  ge.  statline {B
40a0: 79 74 65 73 20 6f 66 20 70 61 79 6c 6f 61 64 7d  ytes of payload}
40b0: 20 24 70 61 79 6c 6f 61 64 20 24 70 61 79 6c 6f   $payload $paylo
40c0: 61 64 5f 70 65 72 63 65 6e 74 0a 20 20 73 74 61  ad_percent.  sta
40d0: 74 6c 69 6e 65 20 7b 41 76 65 72 61 67 65 20 70  tline {Average p
40e0: 61 79 6c 6f 61 64 20 70 65 72 20 65 6e 74 72 79  ayload per entry
40f0: 7d 20 24 61 76 67 5f 70 61 79 6c 6f 61 64 0a 20  } $avg_payload. 
4100: 20 73 74 61 74 6c 69 6e 65 20 7b 41 76 65 72 61   statline {Avera
4110: 67 65 20 75 6e 75 73 65 64 20 62 79 74 65 73 20  ge unused bytes 
4120: 70 65 72 20 65 6e 74 72 79 7d 20 24 61 76 67 5f  per entry} $avg_
4130: 75 6e 75 73 65 64 0a 20 20 69 66 20 7b 5b 69 6e  unused.  if {[in
4140: 66 6f 20 65 78 69 73 74 73 20 61 76 67 5f 66 61  fo exists avg_fa
4150: 6e 6f 75 74 5d 7d 20 7b 0a 20 20 20 20 73 74 61  nout]} {.    sta
4160: 74 6c 69 6e 65 20 7b 41 76 65 72 61 67 65 20 66  tline {Average f
4170: 61 6e 6f 75 74 7d 20 24 61 76 67 5f 66 61 6e 6f  anout} $avg_fano
4180: 75 74 0a 20 20 7d 0a 20 20 73 74 61 74 6c 69 6e  ut.  }.  statlin
4190: 65 20 7b 4d 61 78 69 6d 75 6d 20 70 61 79 6c 6f  e {Maximum paylo
41a0: 61 64 20 70 65 72 20 65 6e 74 72 79 7d 20 24 6d  ad per entry} $m
41b0: 78 5f 70 61 79 6c 6f 61 64 0a 20 20 73 74 61 74  x_payload.  stat
41c0: 6c 69 6e 65 20 7b 45 6e 74 72 69 65 73 20 74 68  line {Entries th
41d0: 61 74 20 75 73 65 20 6f 76 65 72 66 6c 6f 77 7d  at use overflow}
41e0: 20 24 6f 76 66 6c 5f 63 6e 74 20 24 6f 76 66 6c   $ovfl_cnt $ovfl
41f0: 5f 63 6e 74 5f 70 65 72 63 65 6e 74 0a 20 20 69  _cnt_percent.  i
4200: 66 20 7b 24 69 6e 74 5f 70 61 67 65 73 3e 30 7d  f {$int_pages>0}
4210: 20 7b 0a 20 20 20 20 73 74 61 74 6c 69 6e 65 20   {.    statline 
4220: 7b 49 6e 64 65 78 20 70 61 67 65 73 20 75 73 65  {Index pages use
4230: 64 7d 20 24 69 6e 74 5f 70 61 67 65 73 0a 20 20  d} $int_pages.  
4240: 7d 0a 20 20 73 74 61 74 6c 69 6e 65 20 7b 50 72  }.  statline {Pr
4250: 69 6d 61 72 79 20 70 61 67 65 73 20 75 73 65 64  imary pages used
4260: 7d 20 24 6c 65 61 66 5f 70 61 67 65 73 0a 20 20  } $leaf_pages.  
4270: 73 74 61 74 6c 69 6e 65 20 7b 4f 76 65 72 66 6c  statline {Overfl
4280: 6f 77 20 70 61 67 65 73 20 75 73 65 64 7d 20 24  ow pages used} $
4290: 6f 76 66 6c 5f 70 61 67 65 73 0a 20 20 73 74 61  ovfl_pages.  sta
42a0: 74 6c 69 6e 65 20 7b 54 6f 74 61 6c 20 70 61 67  tline {Total pag
42b0: 65 73 20 75 73 65 64 7d 20 24 74 6f 74 61 6c 5f  es used} $total_
42c0: 70 61 67 65 73 0a 20 20 69 66 20 7b 24 69 6e 74  pages.  if {$int
42d0: 5f 75 6e 75 73 65 64 3e 30 7d 20 7b 0a 20 20 20  _unused>0} {.   
42e0: 20 73 65 74 20 69 6e 74 5f 75 6e 75 73 65 64 5f   set int_unused_
42f0: 70 65 72 63 65 6e 74 20 5c 0a 20 20 20 20 20 20  percent \.      
4300: 20 20 20 5b 70 65 72 63 65 6e 74 20 24 69 6e 74     [percent $int
4310: 5f 75 6e 75 73 65 64 20 5b 65 78 70 72 20 7b 24  _unused [expr {$
4320: 69 6e 74 5f 70 61 67 65 73 2a 24 70 61 67 65 53  int_pages*$pageS
4330: 69 7a 65 7d 5d 20 7b 6f 66 20 69 6e 64 65 78 20  ize}] {of index 
4340: 73 70 61 63 65 7d 5d 0a 20 20 20 20 73 74 61 74  space}].    stat
4350: 6c 69 6e 65 20 22 55 6e 75 73 65 64 20 62 79 74  line "Unused byt
4360: 65 73 20 6f 6e 20 69 6e 64 65 78 20 70 61 67 65  es on index page
4370: 73 22 20 24 69 6e 74 5f 75 6e 75 73 65 64 20 24  s" $int_unused $
4380: 69 6e 74 5f 75 6e 75 73 65 64 5f 70 65 72 63 65  int_unused_perce
4390: 6e 74 0a 20 20 7d 0a 20 20 73 74 61 74 6c 69 6e  nt.  }.  statlin
43a0: 65 20 22 55 6e 75 73 65 64 20 62 79 74 65 73 20  e "Unused bytes 
43b0: 6f 6e 20 70 72 69 6d 61 72 79 20 70 61 67 65 73  on primary pages
43c0: 22 20 24 6c 65 61 66 5f 75 6e 75 73 65 64 20 5c  " $leaf_unused \
43d0: 0a 20 20 20 20 20 5b 70 65 72 63 65 6e 74 20 24  .     [percent $
43e0: 6c 65 61 66 5f 75 6e 75 73 65 64 20 5b 65 78 70  leaf_unused [exp
43f0: 72 20 7b 24 6c 65 61 66 5f 70 61 67 65 73 2a 24  r {$leaf_pages*$
4400: 70 61 67 65 53 69 7a 65 7d 5d 20 7b 6f 66 20 70  pageSize}] {of p
4410: 72 69 6d 61 72 79 20 73 70 61 63 65 7d 5d 0a 20  rimary space}]. 
4420: 20 73 74 61 74 6c 69 6e 65 20 22 55 6e 75 73 65   statline "Unuse
4430: 64 20 62 79 74 65 73 20 6f 6e 20 6f 76 65 72 66  d bytes on overf
4440: 6c 6f 77 20 70 61 67 65 73 22 20 24 6f 76 66 6c  low pages" $ovfl
4450: 5f 75 6e 75 73 65 64 20 5c 0a 20 20 20 20 20 5b  _unused \.     [
4460: 70 65 72 63 65 6e 74 20 24 6f 76 66 6c 5f 75 6e  percent $ovfl_un
4470: 75 73 65 64 20 5b 65 78 70 72 20 7b 24 6f 76 66  used [expr {$ovf
4480: 6c 5f 70 61 67 65 73 2a 24 70 61 67 65 53 69 7a  l_pages*$pageSiz
4490: 65 7d 5d 20 7b 6f 66 20 6f 76 65 72 66 6c 6f 77  e}] {of overflow
44a0: 20 73 70 61 63 65 7d 5d 0a 20 20 73 74 61 74 6c   space}].  statl
44b0: 69 6e 65 20 22 55 6e 75 73 65 64 20 62 79 74 65  ine "Unused byte
44c0: 73 20 6f 6e 20 61 6c 6c 20 70 61 67 65 73 22 20  s on all pages" 
44d0: 24 74 6f 74 61 6c 5f 75 6e 75 73 65 64 20 5c 0a  $total_unused \.
44e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5b                 [
44f0: 70 65 72 63 65 6e 74 20 24 74 6f 74 61 6c 5f 75  percent $total_u
4500: 6e 75 73 65 64 20 24 73 74 6f 72 61 67 65 20 7b  nused $storage {
4510: 6f 66 20 61 6c 6c 20 73 70 61 63 65 7d 5d 0a 20  of all space}]. 
4520: 20 72 65 74 75 72 6e 20 31 0a 7d 0a 0a 23 20 43   return 1.}..# C
4530: 61 6c 63 75 6c 61 74 65 20 74 68 65 20 6f 76 65  alculate the ove
4540: 72 68 65 61 64 20 69 6e 20 70 61 67 65 73 20 63  rhead in pages c
4550: 61 75 73 65 64 20 62 79 20 61 75 74 6f 2d 76 61  aused by auto-va
4560: 63 75 75 6d 2e 20 0a 23 0a 23 20 54 68 69 73 20  cuum. .#.# This 
4570: 70 72 6f 63 65 64 75 72 65 20 63 61 6c 63 75 6c  procedure calcul
4580: 61 74 65 73 20 61 6e 64 20 72 65 74 75 72 6e 73  ates and returns
4590: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70   the number of p
45a0: 61 67 65 73 20 75 73 65 64 20 62 79 20 74 68 65  ages used by the
45b0: 20 0a 23 20 61 75 74 6f 2d 76 61 63 75 75 6d 20   .# auto-vacuum 
45c0: 27 70 6f 69 6e 74 65 72 2d 6d 61 70 27 2e 20 49  'pointer-map'. I
45d0: 66 20 74 68 65 20 64 61 74 61 62 61 73 65 20 64  f the database d
45e0: 6f 65 73 20 6e 6f 74 20 73 75 70 70 6f 72 74 20  oes not support 
45f0: 61 75 74 6f 2d 76 61 63 75 75 6d 2c 0a 23 20 74  auto-vacuum,.# t
4600: 68 65 6e 20 30 20 69 73 20 72 65 74 75 72 6e 65  hen 0 is returne
4610: 64 2e 20 54 68 65 20 74 77 6f 20 61 72 67 75 6d  d. The two argum
4620: 65 6e 74 73 20 61 72 65 20 74 68 65 20 73 69 7a  ents are the siz
4630: 65 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73  e of the databas
4640: 65 20 66 69 6c 65 20 69 6e 0a 23 20 70 61 67 65  e file in.# page
4650: 73 20 61 6e 64 20 74 68 65 20 70 61 67 65 20 73  s and the page s
4660: 69 7a 65 20 75 73 65 64 20 62 79 20 74 68 65 20  ize used by the 
4670: 64 61 74 61 62 61 73 65 20 28 69 6e 20 62 79 74  database (in byt
4680: 65 73 29 2e 0a 70 72 6f 63 20 61 75 74 6f 76 61  es)..proc autova
4690: 63 75 75 6d 5f 6f 76 65 72 68 65 61 64 20 7b 66  cuum_overhead {f
46a0: 69 6c 65 50 61 67 65 73 20 70 61 67 65 53 69 7a  ilePages pageSiz
46b0: 65 7d 20 7b 0a 0a 20 20 23 20 52 65 61 64 20 74  e} {..  # Read t
46c0: 68 65 20 76 61 6c 75 65 20 6f 66 20 6d 65 74 61  he value of meta
46d0: 20 34 2e 20 49 66 20 6e 6f 6e 2d 7a 65 72 6f 2c   4. If non-zero,
46e0: 20 74 68 65 6e 20 74 68 65 20 64 61 74 61 62 61   then the databa
46f0: 73 65 20 73 75 70 70 6f 72 74 73 0a 20 20 23 20  se supports.  # 
4700: 61 75 74 6f 2d 76 61 63 75 75 6d 2e 20 49 74 20  auto-vacuum. It 
4710: 77 6f 75 6c 64 20 62 65 20 70 6f 73 73 69 62 6c  would be possibl
4720: 65 20 74 6f 20 75 73 65 20 22 50 52 41 47 4d 41  e to use "PRAGMA
4730: 20 61 75 74 6f 5f 76 61 63 75 75 6d 22 20 69 6e   auto_vacuum" in
4740: 73 74 65 61 64 2c 0a 20 20 23 20 62 75 74 20 74  stead,.  # but t
4750: 68 61 74 20 77 6f 75 6c 64 20 6e 6f 74 20 77 6f  hat would not wo
4760: 72 6b 20 69 66 20 74 68 65 20 53 51 4c 49 54 45  rk if the SQLITE
4770: 5f 4f 4d 49 54 5f 50 52 41 47 4d 41 20 6d 61 63  _OMIT_PRAGMA mac
4780: 72 6f 20 77 61 73 20 64 65 66 69 6e 65 64 0a 20  ro was defined. 
4790: 20 23 20 77 68 65 6e 20 74 68 65 20 6c 69 62 72   # when the libr
47a0: 61 72 79 20 77 61 73 20 62 75 69 6c 74 2e 0a 20  ary was built.. 
47b0: 20 73 65 74 20 6d 65 74 61 34 20 5b 6c 69 6e 64   set meta4 [lind
47c0: 65 78 20 5b 62 74 72 65 65 5f 67 65 74 5f 6d 65  ex [btree_get_me
47d0: 74 61 20 24 3a 3a 44 42 5d 20 34 5d 0a 0a 20 20  ta $::DB] 4]..  
47e0: 23 20 49 66 20 74 68 65 20 64 61 74 61 62 61 73  # If the databas
47f0: 65 20 69 73 20 6e 6f 74 20 61 6e 20 61 75 74 6f  e is not an auto
4800: 2d 76 61 63 75 75 6d 20 64 61 74 61 62 61 73 65  -vacuum database
4810: 20 6f 72 20 74 68 65 20 66 69 6c 65 20 63 6f 6e   or the file con
4820: 73 69 73 74 73 0a 20 20 23 20 6f 66 20 6f 6e 65  sists.  # of one
4830: 20 70 61 67 65 20 6f 6e 6c 79 20 74 68 65 6e 20   page only then 
4840: 74 68 65 72 65 20 69 73 20 6e 6f 20 6f 76 65 72  there is no over
4850: 68 65 61 64 20 66 6f 72 20 61 75 74 6f 2d 76 61  head for auto-va
4860: 63 75 75 6d 2e 20 52 65 74 75 72 6e 20 7a 65 72  cuum. Return zer
4870: 6f 2e 0a 20 20 69 66 20 7b 30 3d 3d 24 6d 65 74  o..  if {0==$met
4880: 61 34 20 7c 7c 20 24 66 69 6c 65 50 61 67 65 73  a4 || $filePages
4890: 3d 3d 31 7d 20 7b 0a 20 20 20 20 72 65 74 75 72  ==1} {.    retur
48a0: 6e 20 30 0a 20 20 7d 0a 0a 20 20 23 20 54 68 65  n 0.  }..  # The
48b0: 20 6e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69   number of entri
48c0: 65 73 20 6f 6e 20 65 61 63 68 20 70 6f 69 6e 74  es on each point
48d0: 65 72 20 6d 61 70 20 70 61 67 65 2e 20 54 68 65  er map page. The
48e0: 20 6c 61 79 6f 75 74 20 6f 66 20 74 68 65 0a 20   layout of the. 
48f0: 20 23 20 64 61 74 61 62 61 73 65 20 66 69 6c 65   # database file
4900: 20 69 73 20 6f 6e 65 20 70 6f 69 6e 74 65 72 2d   is one pointer-
4910: 6d 61 70 20 70 61 67 65 2c 20 66 6f 6c 6c 6f 77  map page, follow
4920: 65 64 20 62 79 20 24 70 74 72 73 50 65 72 50 61  ed by $ptrsPerPa
4930: 67 65 20 6f 74 68 65 72 0a 20 20 23 20 70 61 67  ge other.  # pag
4940: 65 73 2c 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20  es, followed by 
4950: 61 20 70 6f 69 6e 74 65 72 2d 6d 61 70 20 70 61  a pointer-map pa
4960: 67 65 20 65 74 63 2e 20 54 68 65 20 66 69 72 73  ge etc. The firs
4970: 74 20 70 6f 69 6e 74 65 72 2d 6d 61 70 20 70 61  t pointer-map pa
4980: 67 65 0a 20 20 23 20 69 73 20 74 68 65 20 73 65  ge.  # is the se
4990: 63 6f 6e 64 20 70 61 67 65 20 6f 66 20 74 68 65  cond page of the
49a0: 20 66 69 6c 65 20 6f 76 65 72 61 6c 6c 2e 0a 20   file overall.. 
49b0: 20 73 65 74 20 70 74 72 73 50 65 72 50 61 67 65   set ptrsPerPage
49c0: 20 5b 65 78 70 72 20 64 6f 75 62 6c 65 28 24 70   [expr double($p
49d0: 61 67 65 53 69 7a 65 2f 35 29 5d 0a 0a 20 20 23  ageSize/5)]..  #
49e0: 20 52 65 74 75 72 6e 20 74 68 65 20 6e 75 6d 62   Return the numb
49f0: 65 72 20 6f 66 20 70 6f 69 6e 74 65 72 20 6d 61  er of pointer ma
4a00: 70 20 70 61 67 65 73 20 69 6e 20 74 68 65 20 64  p pages in the d
4a10: 61 74 61 62 61 73 65 2e 0a 20 20 72 65 74 75 72  atabase..  retur
4a20: 6e 20 5b 65 78 70 72 20 69 6e 74 28 63 65 69 6c  n [expr int(ceil
4a30: 28 20 28 24 66 69 6c 65 50 61 67 65 73 2d 31 2e  ( ($filePages-1.
4a40: 30 29 2f 28 24 70 74 72 73 50 65 72 50 61 67 65  0)/($ptrsPerPage
4a50: 2b 31 2e 30 29 20 29 29 5d 0a 7d 0a 0a 0a 23 20  +1.0) ))].}...# 
4a60: 43 61 6c 63 75 6c 61 74 65 20 74 68 65 20 73 75  Calculate the su
4a70: 6d 6d 61 72 79 20 73 74 61 74 69 73 74 69 63 73  mmary statistics
4a80: 20 66 6f 72 20 74 68 65 20 64 61 74 61 62 61 73   for the databas
4a90: 65 20 61 6e 64 20 73 74 6f 72 65 20 74 68 65 20  e and store the 
4aa0: 72 65 73 75 6c 74 73 0a 23 20 69 6e 20 54 43 4c  results.# in TCL
4ab0: 20 76 61 72 69 61 62 6c 65 73 2e 20 54 68 65 79   variables. They
4ac0: 20 61 72 65 20 6f 75 74 70 75 74 20 62 65 6c 6f   are output belo
4ad0: 77 2e 20 56 61 72 69 61 62 6c 65 73 20 61 72 65  w. Variables are
4ae0: 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 23 0a 23   as follows:.#.#
4af0: 20 70 61 67 65 53 69 7a 65 3a 20 20 20 20 20 20   pageSize:      
4b00: 53 69 7a 65 20 6f 66 20 65 61 63 68 20 70 61 67  Size of each pag
4b10: 65 20 69 6e 20 62 79 74 65 73 2e 0a 23 20 66 69  e in bytes..# fi
4b20: 6c 65 5f 62 79 74 65 73 3a 20 20 20 20 46 69 6c  le_bytes:    Fil
4b30: 65 20 73 69 7a 65 20 69 6e 20 62 79 74 65 73 2e  e size in bytes.
4b40: 0a 23 20 66 69 6c 65 5f 70 67 63 6e 74 3a 20 20  .# file_pgcnt:  
4b50: 20 20 4e 75 6d 62 65 72 20 6f 66 20 70 61 67 65    Number of page
4b60: 73 20 69 6e 20 74 68 65 20 66 69 6c 65 2e 0a 23  s in the file..#
4b70: 20 66 69 6c 65 5f 70 67 63 6e 74 32 3a 20 20 20   file_pgcnt2:   
4b80: 4e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  Number of pages 
4b90: 69 6e 20 74 68 65 20 66 69 6c 65 20 28 63 61 6c  in the file (cal
4ba0: 63 75 6c 61 74 65 64 29 2e 0a 23 20 61 76 5f 70  culated)..# av_p
4bb0: 67 63 6e 74 3a 20 20 20 20 20 20 50 61 67 65 73  gcnt:      Pages
4bc0: 20 63 6f 6e 73 75 6d 65 64 20 62 79 20 74 68 65   consumed by the
4bd0: 20 61 75 74 6f 2d 76 61 63 75 75 6d 20 70 6f 69   auto-vacuum poi
4be0: 6e 74 65 72 2d 6d 61 70 2e 0a 23 20 61 76 5f 70  nter-map..# av_p
4bf0: 65 72 63 65 6e 74 3a 20 20 20 20 50 65 72 63 65  ercent:    Perce
4c00: 6e 74 61 67 65 20 6f 66 20 74 68 65 20 66 69 6c  ntage of the fil
4c10: 65 20 63 6f 6e 73 75 6d 65 64 20 62 79 20 61 75  e consumed by au
4c20: 74 6f 2d 76 61 63 75 75 6d 20 70 6f 69 6e 74 65  to-vacuum pointe
4c30: 72 2d 6d 61 70 2e 0a 23 20 69 6e 75 73 65 5f 70  r-map..# inuse_p
4c40: 67 63 6e 74 3a 20 20 20 44 61 74 61 20 70 61 67  gcnt:   Data pag
4c50: 65 73 20 69 6e 20 74 68 65 20 66 69 6c 65 2e 0a  es in the file..
4c60: 23 20 69 6e 75 73 65 5f 70 65 72 63 65 6e 74 3a  # inuse_percent:
4c70: 20 50 65 72 63 65 6e 74 61 67 65 20 6f 66 20 70   Percentage of p
4c80: 61 67 65 73 20 75 73 65 64 20 74 6f 20 73 74 6f  ages used to sto
4c90: 72 65 20 64 61 74 61 2e 0a 23 20 66 72 65 65 5f  re data..# free_
4ca0: 70 67 63 6e 74 3a 20 20 20 20 46 72 65 65 20 70  pgcnt:    Free p
4cb0: 61 67 65 73 20 63 61 6c 63 75 6c 61 74 65 64 20  ages calculated 
4cc0: 61 73 20 28 3c 74 6f 74 61 6c 20 70 61 67 65 73  as (<total pages
4cd0: 3e 20 2d 20 3c 69 6e 2d 75 73 65 20 70 61 67 65  > - <in-use page
4ce0: 73 3e 29 0a 23 20 66 72 65 65 5f 70 67 63 6e 74  s>).# free_pgcnt
4cf0: 32 3a 20 20 20 46 72 65 65 20 70 61 67 65 73 20  2:   Free pages 
4d00: 69 6e 20 74 68 65 20 66 69 6c 65 20 61 63 63 6f  in the file acco
4d10: 72 64 69 6e 67 20 74 6f 20 74 68 65 20 66 69 6c  rding to the fil
4d20: 65 20 68 65 61 64 65 72 2e 0a 23 20 66 72 65 65  e header..# free
4d30: 5f 70 65 72 63 65 6e 74 3a 20 20 50 65 72 63 65  _percent:  Perce
4d40: 6e 74 61 67 65 20 6f 66 20 66 69 6c 65 20 63 6f  ntage of file co
4d50: 6e 73 75 6d 65 64 20 62 79 20 66 72 65 65 20 70  nsumed by free p
4d60: 61 67 65 73 20 28 63 61 6c 63 75 6c 61 74 65 64  ages (calculated
4d70: 29 2e 0a 23 20 66 72 65 65 5f 70 65 72 63 65 6e  )..# free_percen
4d80: 74 32 3a 20 50 65 72 63 65 6e 74 61 67 65 20 6f  t2: Percentage o
4d90: 66 20 66 69 6c 65 20 63 6f 6e 73 75 6d 65 64 20  f file consumed 
4da0: 62 79 20 66 72 65 65 20 70 61 67 65 73 20 28 68  by free pages (h
4db0: 65 61 64 65 72 29 2e 0a 23 20 6e 74 61 62 6c 65  eader)..# ntable
4dc0: 3a 20 20 20 20 20 20 20 20 4e 75 6d 62 65 72 20  :        Number 
4dd0: 6f 66 20 74 61 62 6c 65 73 20 69 6e 20 74 68 65  of tables in the
4de0: 20 64 62 2e 0a 23 20 6e 69 6e 64 65 78 3a 20 20   db..# nindex:  
4df0: 20 20 20 20 20 20 4e 75 6d 62 65 72 20 6f 66 20        Number of 
4e00: 69 6e 64 69 63 65 73 20 69 6e 20 74 68 65 20 64  indices in the d
4e10: 62 2e 0a 23 20 6e 61 75 74 6f 69 6e 64 65 78 3a  b..# nautoindex:
4e20: 20 20 20 20 4e 75 6d 62 65 72 20 6f 66 20 69 6e      Number of in
4e30: 64 69 63 65 73 20 63 72 65 61 74 65 64 20 61 75  dices created au
4e40: 74 6f 6d 61 74 69 63 61 6c 6c 79 2e 0a 23 20 6e  tomatically..# n
4e50: 6d 61 6e 69 6e 64 65 78 3a 20 20 20 20 20 4e 75  manindex:     Nu
4e60: 6d 62 65 72 20 6f 66 20 69 6e 64 69 63 65 73 20  mber of indices 
4e70: 63 72 65 61 74 65 64 20 6d 61 6e 75 61 6c 6c 79  created manually
4e80: 2e 0a 23 20 75 73 65 72 5f 70 61 79 6c 6f 61 64  ..# user_payload
4e90: 3a 20 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74  :  Number of byt
4ea0: 65 73 20 6f 66 20 70 61 79 6c 6f 61 64 20 69 6e  es of payload in
4eb0: 20 74 61 62 6c 65 20 62 74 72 65 65 73 20 0a 23   table btrees .#
4ec0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4ed0: 28 6e 6f 74 20 69 6e 63 6c 75 64 69 6e 67 20 73  (not including s
4ee0: 71 6c 69 74 65 5f 6d 61 73 74 65 72 29 0a 23 20  qlite_master).# 
4ef0: 75 73 65 72 5f 70 65 72 63 65 6e 74 3a 20 20 24  user_percent:  $
4f00: 75 73 65 72 5f 70 61 79 6c 6f 61 64 20 61 73 20  user_payload as 
4f10: 61 20 70 65 72 63 65 6e 74 61 67 65 20 6f 66 20  a percentage of 
4f20: 74 6f 74 61 6c 20 66 69 6c 65 20 73 69 7a 65 2e  total file size.
4f30: 0a 0a 73 65 74 20 66 69 6c 65 5f 62 79 74 65 73  ..set file_bytes
4f40: 20 20 5b 66 69 6c 65 20 73 69 7a 65 20 24 66 69    [file size $fi
4f50: 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 5d 0a 73  le_to_analyze].s
4f60: 65 74 20 66 69 6c 65 5f 70 67 63 6e 74 20 20 5b  et file_pgcnt  [
4f70: 65 78 70 72 20 7b 24 66 69 6c 65 5f 62 79 74 65  expr {$file_byte
4f80: 73 2f 24 70 61 67 65 53 69 7a 65 7d 5d 0a 0a 73  s/$pageSize}]..s
4f90: 65 74 20 61 76 5f 70 67 63 6e 74 20 20 20 20 5b  et av_pgcnt    [
4fa0: 61 75 74 6f 76 61 63 75 75 6d 5f 6f 76 65 72 68  autovacuum_overh
4fb0: 65 61 64 20 24 66 69 6c 65 5f 70 67 63 6e 74 20  ead $file_pgcnt 
4fc0: 24 70 61 67 65 53 69 7a 65 5d 0a 73 65 74 20 61  $pageSize].set a
4fd0: 76 5f 70 65 72 63 65 6e 74 20 20 5b 70 65 72 63  v_percent  [perc
4fe0: 65 6e 74 20 24 61 76 5f 70 67 63 6e 74 20 24 66  ent $av_pgcnt $f
4ff0: 69 6c 65 5f 70 67 63 6e 74 5d 0a 0a 73 65 74 20  ile_pgcnt]..set 
5000: 73 71 6c 20 7b 53 45 4c 45 43 54 20 73 75 6d 28  sql {SELECT sum(
5010: 6c 65 61 66 5f 70 61 67 65 73 2b 69 6e 74 5f 70  leaf_pages+int_p
5020: 61 67 65 73 2b 6f 76 66 6c 5f 70 61 67 65 73 29  ages+ovfl_pages)
5030: 20 46 52 4f 4d 20 73 70 61 63 65 5f 75 73 65 64   FROM space_used
5040: 7d 0a 73 65 74 20 69 6e 75 73 65 5f 70 67 63 6e  }.set inuse_pgcn
5050: 74 20 20 20 5b 65 78 70 72 20 69 6e 74 28 5b 6d  t   [expr int([m
5060: 65 6d 20 65 76 61 6c 20 24 73 71 6c 5d 29 5d 0a  em eval $sql])].
5070: 73 65 74 20 69 6e 75 73 65 5f 70 65 72 63 65 6e  set inuse_percen
5080: 74 20 5b 70 65 72 63 65 6e 74 20 24 69 6e 75 73  t [percent $inus
5090: 65 5f 70 67 63 6e 74 20 24 66 69 6c 65 5f 70 67  e_pgcnt $file_pg
50a0: 63 6e 74 5d 0a 0a 73 65 74 20 66 72 65 65 5f 70  cnt]..set free_p
50b0: 67 63 6e 74 20 20 20 20 5b 65 78 70 72 20 24 66  gcnt    [expr $f
50c0: 69 6c 65 5f 70 67 63 6e 74 2d 24 69 6e 75 73 65  ile_pgcnt-$inuse
50d0: 5f 70 67 63 6e 74 2d 24 61 76 5f 70 67 63 6e 74  _pgcnt-$av_pgcnt
50e0: 5d 0a 73 65 74 20 66 72 65 65 5f 70 65 72 63 65  ].set free_perce
50f0: 6e 74 20 20 5b 70 65 72 63 65 6e 74 20 24 66 72  nt  [percent $fr
5100: 65 65 5f 70 67 63 6e 74 20 24 66 69 6c 65 5f 70  ee_pgcnt $file_p
5110: 67 63 6e 74 5d 0a 73 65 74 20 66 72 65 65 5f 70  gcnt].set free_p
5120: 67 63 6e 74 32 20 20 20 5b 6c 69 6e 64 65 78 20  gcnt2   [lindex 
5130: 5b 62 74 72 65 65 5f 67 65 74 5f 6d 65 74 61 20  [btree_get_meta 
5140: 24 44 42 5d 20 30 5d 0a 73 65 74 20 66 72 65 65  $DB] 0].set free
5150: 5f 70 65 72 63 65 6e 74 32 20 5b 70 65 72 63 65  _percent2 [perce
5160: 6e 74 20 24 66 72 65 65 5f 70 67 63 6e 74 32 20  nt $free_pgcnt2 
5170: 24 66 69 6c 65 5f 70 67 63 6e 74 5d 0a 0a 73 65  $file_pgcnt]..se
5180: 74 20 66 69 6c 65 5f 70 67 63 6e 74 32 20 5b 65  t file_pgcnt2 [e
5190: 78 70 72 20 7b 24 69 6e 75 73 65 5f 70 67 63 6e  xpr {$inuse_pgcn
51a0: 74 2b 24 66 72 65 65 5f 70 67 63 6e 74 32 2b 24  t+$free_pgcnt2+$
51b0: 61 76 5f 70 67 63 6e 74 7d 5d 0a 0a 73 65 74 20  av_pgcnt}]..set 
51c0: 6e 74 61 62 6c 65 20 5b 64 62 20 65 76 61 6c 20  ntable [db eval 
51d0: 7b 53 45 4c 45 43 54 20 63 6f 75 6e 74 28 2a 29  {SELECT count(*)
51e0: 2b 31 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d  +1 FROM sqlite_m
51f0: 61 73 74 65 72 20 57 48 45 52 45 20 74 79 70 65  aster WHERE type
5200: 3d 27 74 61 62 6c 65 27 7d 5d 0a 73 65 74 20 6e  ='table'}].set n
5210: 69 6e 64 65 78 20 5b 64 62 20 65 76 61 6c 20 7b  index [db eval {
5220: 53 45 4c 45 43 54 20 63 6f 75 6e 74 28 2a 29 20  SELECT count(*) 
5230: 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74  FROM sqlite_mast
5240: 65 72 20 57 48 45 52 45 20 74 79 70 65 3d 27 69  er WHERE type='i
5250: 6e 64 65 78 27 7d 5d 0a 73 65 74 20 73 71 6c 20  ndex'}].set sql 
5260: 7b 53 45 4c 45 43 54 20 63 6f 75 6e 74 28 2a 29  {SELECT count(*)
5270: 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73   FROM sqlite_mas
5280: 74 65 72 20 57 48 45 52 45 20 6e 61 6d 65 20 4c  ter WHERE name L
5290: 49 4b 45 20 27 73 71 6c 69 74 65 5f 61 75 74 6f  IKE 'sqlite_auto
52a0: 69 6e 64 65 78 25 27 7d 0a 73 65 74 20 6e 61 75  index%'}.set nau
52b0: 74 6f 69 6e 64 65 78 20 5b 64 62 20 65 76 61 6c  toindex [db eval
52c0: 20 24 73 71 6c 5d 0a 73 65 74 20 6e 6d 61 6e 69   $sql].set nmani
52d0: 6e 64 65 78 20 5b 65 78 70 72 20 7b 24 6e 69 6e  ndex [expr {$nin
52e0: 64 65 78 2d 24 6e 61 75 74 6f 69 6e 64 65 78 7d  dex-$nautoindex}
52f0: 5d 0a 0a 23 20 73 65 74 20 74 6f 74 61 6c 5f 70  ]..# set total_p
5300: 61 79 6c 6f 61 64 20 5b 6d 65 6d 20 65 76 61 6c  ayload [mem eval
5310: 20 22 53 45 4c 45 43 54 20 73 75 6d 28 70 61 79   "SELECT sum(pay
5320: 6c 6f 61 64 29 20 46 52 4f 4d 20 73 70 61 63 65  load) FROM space
5330: 5f 75 73 65 64 22 5d 0a 73 65 74 20 75 73 65 72  _used"].set user
5340: 5f 70 61 79 6c 6f 61 64 20 5b 6d 65 6d 20 6f 6e  _payload [mem on
5350: 65 20 7b 53 45 4c 45 43 54 20 69 6e 74 28 73 75  e {SELECT int(su
5360: 6d 28 70 61 79 6c 6f 61 64 29 29 20 46 52 4f 4d  m(payload)) FROM
5370: 20 73 70 61 63 65 5f 75 73 65 64 0a 20 20 20 20   space_used.    
5380: 20 57 48 45 52 45 20 4e 4f 54 20 69 73 5f 69 6e   WHERE NOT is_in
5390: 64 65 78 20 41 4e 44 20 6e 61 6d 65 20 4e 4f 54  dex AND name NOT
53a0: 20 4c 49 4b 45 20 27 73 71 6c 69 74 65 5f 6d 61   LIKE 'sqlite_ma
53b0: 73 74 65 72 27 7d 5d 0a 73 65 74 20 75 73 65 72  ster'}].set user
53c0: 5f 70 65 72 63 65 6e 74 20 5b 70 65 72 63 65 6e  _percent [percen
53d0: 74 20 24 75 73 65 72 5f 70 61 79 6c 6f 61 64 20  t $user_payload 
53e0: 24 66 69 6c 65 5f 62 79 74 65 73 5d 0a 0a 23 20  $file_bytes]..# 
53f0: 4f 75 74 70 75 74 20 74 68 65 20 73 75 6d 6d 61  Output the summa
5400: 72 79 20 73 74 61 74 69 73 74 69 63 73 20 63 61  ry statistics ca
5410: 6c 63 75 6c 61 74 65 64 20 61 62 6f 76 65 2e 0a  lculated above..
5420: 23 0a 70 75 74 73 20 22 2f 2a 2a 20 44 69 73 6b  #.puts "/** Disk
5430: 2d 53 70 61 63 65 20 55 74 69 6c 69 7a 61 74 69  -Space Utilizati
5440: 6f 6e 20 52 65 70 6f 72 74 20 46 6f 72 20 24 66  on Report For $f
5450: 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 22 0a  ile_to_analyze".
5460: 70 75 74 73 20 22 2a 2a 2a 20 41 73 20 6f 66 20  puts "*** As of 
5470: 5b 63 6c 6f 63 6b 20 66 6f 72 6d 61 74 20 5b 63  [clock format [c
5480: 6c 6f 63 6b 20 73 65 63 6f 6e 64 73 5d 20 2d 66  lock seconds] -f
5490: 6f 72 6d 61 74 20 7b 25 59 2d 25 62 2d 25 64 20  ormat {%Y-%b-%d 
54a0: 25 48 3a 25 4d 3a 25 53 7d 5d 22 0a 70 75 74 73  %H:%M:%S}]".puts
54b0: 20 22 22 0a 73 74 61 74 6c 69 6e 65 20 7b 50 61   "".statline {Pa
54c0: 67 65 20 73 69 7a 65 20 69 6e 20 62 79 74 65 73  ge size in bytes
54d0: 7d 20 24 70 61 67 65 53 69 7a 65 0a 73 74 61 74  } $pageSize.stat
54e0: 6c 69 6e 65 20 7b 50 61 67 65 73 20 69 6e 20 74  line {Pages in t
54f0: 68 65 20 77 68 6f 6c 65 20 66 69 6c 65 20 28 6d  he whole file (m
5500: 65 61 73 75 72 65 64 29 7d 20 24 66 69 6c 65 5f  easured)} $file_
5510: 70 67 63 6e 74 0a 73 74 61 74 6c 69 6e 65 20 7b  pgcnt.statline {
5520: 50 61 67 65 73 20 69 6e 20 74 68 65 20 77 68 6f  Pages in the who
5530: 6c 65 20 66 69 6c 65 20 28 63 61 6c 63 75 6c 61  le file (calcula
5540: 74 65 64 29 7d 20 24 66 69 6c 65 5f 70 67 63 6e  ted)} $file_pgcn
5550: 74 32 0a 73 74 61 74 6c 69 6e 65 20 7b 50 61 67  t2.statline {Pag
5560: 65 73 20 74 68 61 74 20 73 74 6f 72 65 20 64 61  es that store da
5570: 74 61 7d 20 24 69 6e 75 73 65 5f 70 67 63 6e 74  ta} $inuse_pgcnt
5580: 20 24 69 6e 75 73 65 5f 70 65 72 63 65 6e 74 0a   $inuse_percent.
5590: 73 74 61 74 6c 69 6e 65 20 7b 50 61 67 65 73 20  statline {Pages 
55a0: 6f 6e 20 74 68 65 20 66 72 65 65 6c 69 73 74 20  on the freelist 
55b0: 28 70 65 72 20 68 65 61 64 65 72 29 7d 20 24 66  (per header)} $f
55c0: 72 65 65 5f 70 67 63 6e 74 32 20 24 66 72 65 65  ree_pgcnt2 $free
55d0: 5f 70 65 72 63 65 6e 74 32 0a 73 74 61 74 6c 69  _percent2.statli
55e0: 6e 65 20 7b 50 61 67 65 73 20 6f 6e 20 74 68 65  ne {Pages on the
55f0: 20 66 72 65 65 6c 69 73 74 20 28 63 61 6c 63 75   freelist (calcu
5600: 6c 61 74 65 64 29 7d 20 24 66 72 65 65 5f 70 67  lated)} $free_pg
5610: 63 6e 74 20 24 66 72 65 65 5f 70 65 72 63 65 6e  cnt $free_percen
5620: 74 0a 73 74 61 74 6c 69 6e 65 20 7b 50 61 67 65  t.statline {Page
5630: 73 20 6f 66 20 61 75 74 6f 2d 76 61 63 75 75 6d  s of auto-vacuum
5640: 20 6f 76 65 72 68 65 61 64 7d 20 24 61 76 5f 70   overhead} $av_p
5650: 67 63 6e 74 20 24 61 76 5f 70 65 72 63 65 6e 74  gcnt $av_percent
5660: 0a 73 74 61 74 6c 69 6e 65 20 7b 4e 75 6d 62 65  .statline {Numbe
5670: 72 20 6f 66 20 74 61 62 6c 65 73 20 69 6e 20 74  r of tables in t
5680: 68 65 20 64 61 74 61 62 61 73 65 7d 20 24 6e 74  he database} $nt
5690: 61 62 6c 65 0a 73 74 61 74 6c 69 6e 65 20 7b 4e  able.statline {N
56a0: 75 6d 62 65 72 20 6f 66 20 69 6e 64 69 63 65 73  umber of indices
56b0: 7d 20 24 6e 69 6e 64 65 78 0a 73 74 61 74 6c 69  } $nindex.statli
56c0: 6e 65 20 7b 4e 75 6d 62 65 72 20 6f 66 20 6e 61  ne {Number of na
56d0: 6d 65 64 20 69 6e 64 69 63 65 73 7d 20 24 6e 6d  med indices} $nm
56e0: 61 6e 69 6e 64 65 78 0a 73 74 61 74 6c 69 6e 65  anindex.statline
56f0: 20 7b 41 75 74 6f 6d 61 74 69 63 61 6c 6c 79 20   {Automatically 
5700: 67 65 6e 65 72 61 74 65 64 20 69 6e 64 69 63 65  generated indice
5710: 73 7d 20 24 6e 61 75 74 6f 69 6e 64 65 78 0a 73  s} $nautoindex.s
5720: 74 61 74 6c 69 6e 65 20 7b 53 69 7a 65 20 6f 66  tatline {Size of
5730: 20 74 68 65 20 66 69 6c 65 20 69 6e 20 62 79 74   the file in byt
5740: 65 73 7d 20 24 66 69 6c 65 5f 62 79 74 65 73 0a  es} $file_bytes.
5750: 73 74 61 74 6c 69 6e 65 20 7b 42 79 74 65 73 20  statline {Bytes 
5760: 6f 66 20 75 73 65 72 20 70 61 79 6c 6f 61 64 20  of user payload 
5770: 73 74 6f 72 65 64 7d 20 24 75 73 65 72 5f 70 61  stored} $user_pa
5780: 79 6c 6f 61 64 20 24 75 73 65 72 5f 70 65 72 63  yload $user_perc
5790: 65 6e 74 0a 0a 23 20 4f 75 74 70 75 74 20 74 61  ent..# Output ta
57a0: 62 6c 65 20 72 61 6e 6b 69 6e 67 73 0a 23 0a 70  ble rankings.#.p
57b0: 75 74 73 20 22 22 0a 70 75 74 73 20 22 2a 2a 2a  uts "".puts "***
57c0: 20 50 61 67 65 20 63 6f 75 6e 74 73 20 66 6f 72   Page counts for
57d0: 20 61 6c 6c 20 74 61 62 6c 65 73 20 77 69 74 68   all tables with
57e0: 20 74 68 65 69 72 20 69 6e 64 69 63 65 73 20 2a   their indices *
57f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5800: 2a 2a 2a 22 0a 70 75 74 73 20 22 22 0a 6d 65 6d  ***".puts "".mem
5810: 20 65 76 61 6c 20 7b 53 45 4c 45 43 54 20 74 62   eval {SELECT tb
5820: 6c 6e 61 6d 65 2c 20 63 6f 75 6e 74 28 2a 29 20  lname, count(*) 
5830: 41 53 20 63 6e 74 2c 20 0a 20 20 20 20 20 20 20  AS cnt, .       
5840: 20 20 20 20 20 20 20 69 6e 74 28 73 75 6d 28 69         int(sum(i
5850: 6e 74 5f 70 61 67 65 73 2b 6c 65 61 66 5f 70 61  nt_pages+leaf_pa
5860: 67 65 73 2b 6f 76 66 6c 5f 70 61 67 65 73 29 29  ges+ovfl_pages))
5870: 20 41 53 20 73 69 7a 65 0a 20 20 20 20 20 20 20   AS size.       
5880: 20 20 20 46 52 4f 4d 20 73 70 61 63 65 5f 75 73     FROM space_us
5890: 65 64 20 47 52 4f 55 50 20 42 59 20 74 62 6c 6e  ed GROUP BY tbln
58a0: 61 6d 65 20 4f 52 44 45 52 20 42 59 20 73 69 7a  ame ORDER BY siz
58b0: 65 2b 30 20 44 45 53 43 2c 20 74 62 6c 6e 61 6d  e+0 DESC, tblnam
58c0: 65 7d 20 7b 7d 20 7b 0a 20 20 73 74 61 74 6c 69  e} {} {.  statli
58d0: 6e 65 20 5b 73 74 72 69 6e 67 20 74 6f 75 70 70  ne [string toupp
58e0: 65 72 20 24 74 62 6c 6e 61 6d 65 5d 20 24 73 69  er $tblname] $si
58f0: 7a 65 20 5b 70 65 72 63 65 6e 74 20 24 73 69 7a  ze [percent $siz
5900: 65 20 24 66 69 6c 65 5f 70 67 63 6e 74 5d 0a 7d  e $file_pgcnt].}
5910: 0a 0a 23 20 4f 75 74 70 75 74 20 73 75 62 72 65  ..# Output subre
5920: 70 6f 72 74 73 0a 23 0a 69 66 20 7b 24 6e 69 6e  ports.#.if {$nin
5930: 64 65 78 3e 30 7d 20 7b 0a 20 20 73 75 62 72 65  dex>0} {.  subre
5940: 70 6f 72 74 20 7b 41 6c 6c 20 74 61 62 6c 65 73  port {All tables
5950: 20 61 6e 64 20 69 6e 64 69 63 65 73 7d 20 31 0a   and indices} 1.
5960: 7d 0a 73 75 62 72 65 70 6f 72 74 20 7b 41 6c 6c  }.subreport {All
5970: 20 74 61 62 6c 65 73 7d 20 7b 4e 4f 54 20 69 73   tables} {NOT is
5980: 5f 69 6e 64 65 78 7d 0a 69 66 20 7b 24 6e 69 6e  _index}.if {$nin
5990: 64 65 78 3e 30 7d 20 7b 0a 20 20 73 75 62 72 65  dex>0} {.  subre
59a0: 70 6f 72 74 20 7b 41 6c 6c 20 69 6e 64 69 63 65  port {All indice
59b0: 73 7d 20 7b 69 73 5f 69 6e 64 65 78 7d 0a 7d 0a  s} {is_index}.}.
59c0: 66 6f 72 65 61 63 68 20 74 62 6c 20 5b 6d 65 6d  foreach tbl [mem
59d0: 20 65 76 61 6c 20 7b 53 45 4c 45 43 54 20 6e 61   eval {SELECT na
59e0: 6d 65 20 46 52 4f 4d 20 73 70 61 63 65 5f 75 73  me FROM space_us
59f0: 65 64 20 57 48 45 52 45 20 4e 4f 54 20 69 73 5f  ed WHERE NOT is_
5a00: 69 6e 64 65 78 0a 20 20 20 20 20 20 20 20 20 20  index.          
5a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 4f 52 44               ORD
5a20: 45 52 20 42 59 20 6e 61 6d 65 7d 5d 20 7b 0a 20  ER BY name}] {. 
5a30: 20 72 65 67 73 75 62 20 27 20 24 74 62 6c 20 27   regsub ' $tbl '
5a40: 27 20 71 6e 0a 20 20 73 65 74 20 6e 61 6d 65 20  ' qn.  set name 
5a50: 5b 73 74 72 69 6e 67 20 74 6f 75 70 70 65 72 20  [string toupper 
5a60: 24 74 62 6c 5d 0a 20 20 73 65 74 20 6e 20 5b 6d  $tbl].  set n [m
5a70: 65 6d 20 65 76 61 6c 20 22 53 45 4c 45 43 54 20  em eval "SELECT 
5a80: 63 6f 75 6e 74 28 2a 29 20 46 52 4f 4d 20 73 70  count(*) FROM sp
5a90: 61 63 65 5f 75 73 65 64 20 57 48 45 52 45 20 74  ace_used WHERE t
5aa0: 62 6c 6e 61 6d 65 3d 27 24 71 6e 27 22 5d 0a 20  blname='$qn'"]. 
5ab0: 20 69 66 20 7b 24 6e 3e 31 7d 20 7b 0a 20 20 20   if {$n>1} {.   
5ac0: 20 73 75 62 72 65 70 6f 72 74 20 22 54 61 62 6c   subreport "Tabl
5ad0: 65 20 24 6e 61 6d 65 20 61 6e 64 20 61 6c 6c 20  e $name and all 
5ae0: 69 74 73 20 69 6e 64 69 63 65 73 22 20 22 74 62  its indices" "tb
5af0: 6c 6e 61 6d 65 3d 27 24 71 6e 27 22 0a 20 20 20  lname='$qn'".   
5b00: 20 73 75 62 72 65 70 6f 72 74 20 22 54 61 62 6c   subreport "Tabl
5b10: 65 20 24 6e 61 6d 65 20 77 2f 6f 20 61 6e 79 20  e $name w/o any 
5b20: 69 6e 64 69 63 65 73 22 20 22 6e 61 6d 65 3d 27  indices" "name='
5b30: 24 71 6e 27 22 0a 20 20 20 20 73 75 62 72 65 70  $qn'".    subrep
5b40: 6f 72 74 20 22 49 6e 64 69 63 65 73 20 6f 66 20  ort "Indices of 
5b50: 74 61 62 6c 65 20 24 6e 61 6d 65 22 20 22 74 62  table $name" "tb
5b60: 6c 6e 61 6d 65 3d 27 24 71 6e 27 20 41 4e 44 20  lname='$qn' AND 
5b70: 69 73 5f 69 6e 64 65 78 22 0a 20 20 7d 20 65 6c  is_index".  } el
5b80: 73 65 20 7b 0a 20 20 20 20 73 75 62 72 65 70 6f  se {.    subrepo
5b90: 72 74 20 22 54 61 62 6c 65 20 24 6e 61 6d 65 22  rt "Table $name"
5ba0: 20 22 6e 61 6d 65 3d 27 24 71 6e 27 22 0a 20 20   "name='$qn'".  
5bb0: 7d 0a 7d 0a 0a 23 20 4f 75 74 70 75 74 20 69 6e  }.}..# Output in
5bc0: 73 74 72 75 63 74 69 6f 6e 73 20 6f 6e 20 77 68  structions on wh
5bd0: 61 74 20 74 68 65 20 6e 75 6d 62 65 72 73 20 61  at the numbers a
5be0: 62 6f 76 65 20 6d 65 61 6e 2e 0a 23 0a 70 75 74  bove mean..#.put
5bf0: 73 20 7b 0a 2a 2a 2a 20 44 65 66 69 6e 69 74 69  s {.*** Definiti
5c00: 6f 6e 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ons ************
5c10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5c20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5c30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 0a 50 61 67 65  **********..Page
5c40: 20 73 69 7a 65 20 69 6e 20 62 79 74 65 73 0a 0a   size in bytes..
5c50: 20 20 20 20 54 68 65 20 6e 75 6d 62 65 72 20 6f      The number o
5c60: 66 20 62 79 74 65 73 20 69 6e 20 61 20 73 69 6e  f bytes in a sin
5c70: 67 6c 65 20 70 61 67 65 20 6f 66 20 74 68 65 20  gle page of the 
5c80: 64 61 74 61 62 61 73 65 20 66 69 6c 65 2e 20 20  database file.  
5c90: 0a 20 20 20 20 55 73 75 61 6c 6c 79 20 31 30 32  .    Usually 102
5ca0: 34 2e 0a 0a 4e 75 6d 62 65 72 20 6f 66 20 70 61  4...Number of pa
5cb0: 67 65 73 20 69 6e 20 74 68 65 20 77 68 6f 6c 65  ges in the whole
5cc0: 20 66 69 6c 65 0a 7d 0a 70 75 74 73 20 5c 0a 22   file.}.puts \."
5cd0: 20 20 20 20 54 68 65 20 6e 75 6d 62 65 72 20 6f      The number o
5ce0: 66 20 24 70 61 67 65 53 69 7a 65 2d 62 79 74 65  f $pageSize-byte
5cf0: 20 70 61 67 65 73 20 74 68 61 74 20 67 6f 20 69   pages that go i
5d00: 6e 74 6f 20 66 6f 72 6d 69 6e 67 20 74 68 65 20  nto forming the 
5d10: 63 6f 6d 70 6c 65 74 65 0a 20 20 20 20 64 61 74  complete.    dat
5d20: 61 62 61 73 65 22 0a 70 75 74 73 20 5c 0a 7b 0a  abase".puts \.{.
5d30: 50 61 67 65 73 20 74 68 61 74 20 73 74 6f 72 65  Pages that store
5d40: 20 64 61 74 61 0a 0a 20 20 20 20 54 68 65 20 6e   data..    The n
5d50: 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 74  umber of pages t
5d60: 68 61 74 20 73 74 6f 72 65 20 64 61 74 61 2c 20  hat store data, 
5d70: 65 69 74 68 65 72 20 61 73 20 70 72 69 6d 61 72  either as primar
5d80: 79 20 42 2a 54 72 65 65 20 70 61 67 65 73 20 6f  y B*Tree pages o
5d90: 72 0a 20 20 20 20 61 73 20 6f 76 65 72 66 6c 6f  r.    as overflo
5da0: 77 20 70 61 67 65 73 2e 20 20 54 68 65 20 6e 75  w pages.  The nu
5db0: 6d 62 65 72 20 61 74 20 74 68 65 20 72 69 67 68  mber at the righ
5dc0: 74 20 69 73 20 74 68 65 20 64 61 74 61 20 70 61  t is the data pa
5dd0: 67 65 73 20 64 69 76 69 64 65 64 20 62 79 0a 20  ges divided by. 
5de0: 20 20 20 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d     the total num
5df0: 62 65 72 20 6f 66 20 70 61 67 65 73 20 69 6e 20  ber of pages in 
5e00: 74 68 65 20 66 69 6c 65 2e 0a 0a 50 61 67 65 73  the file...Pages
5e10: 20 6f 6e 20 74 68 65 20 66 72 65 65 6c 69 73 74   on the freelist
5e20: 0a 0a 20 20 20 20 54 68 65 20 6e 75 6d 62 65 72  ..    The number
5e30: 20 6f 66 20 70 61 67 65 73 20 74 68 61 74 20 61   of pages that a
5e40: 72 65 20 6e 6f 74 20 63 75 72 72 65 6e 74 6c 79  re not currently
5e50: 20 69 6e 20 75 73 65 20 62 75 74 20 61 72 65 20   in use but are 
5e60: 72 65 73 65 72 76 65 64 20 66 6f 72 0a 20 20 20  reserved for.   
5e70: 20 66 75 74 75 72 65 20 75 73 65 2e 20 20 54 68   future use.  Th
5e80: 65 20 70 65 72 63 65 6e 74 61 67 65 20 61 74 20  e percentage at 
5e90: 74 68 65 20 72 69 67 68 74 20 69 73 20 74 68 65  the right is the
5ea0: 20 6e 75 6d 62 65 72 20 6f 66 20 66 72 65 65 6c   number of freel
5eb0: 69 73 74 20 70 61 67 65 73 0a 20 20 20 20 64 69  ist pages.    di
5ec0: 76 69 64 65 64 20 62 79 20 74 68 65 20 74 6f 74  vided by the tot
5ed0: 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67  al number of pag
5ee0: 65 73 20 69 6e 20 74 68 65 20 66 69 6c 65 2e 0a  es in the file..
5ef0: 0a 50 61 67 65 73 20 6f 66 20 61 75 74 6f 2d 76  .Pages of auto-v
5f00: 61 63 75 75 6d 20 6f 76 65 72 68 65 61 64 0a 0a  acuum overhead..
5f10: 20 20 20 20 54 68 65 20 6e 75 6d 62 65 72 20 6f      The number o
5f20: 66 20 70 61 67 65 73 20 74 68 61 74 20 73 74 6f  f pages that sto
5f30: 72 65 20 64 61 74 61 20 75 73 65 64 20 62 79 20  re data used by 
5f40: 74 68 65 20 64 61 74 61 62 61 73 65 20 74 6f 20  the database to 
5f50: 66 61 63 69 6c 69 74 61 74 65 0a 20 20 20 20 61  facilitate.    a
5f60: 75 74 6f 2d 76 61 63 75 75 6d 2e 20 54 68 69 73  uto-vacuum. This
5f70: 20 69 73 20 7a 65 72 6f 20 66 6f 72 20 64 61 74   is zero for dat
5f80: 61 62 61 73 65 73 20 74 68 61 74 20 64 6f 20 6e  abases that do n
5f90: 6f 74 20 73 75 70 70 6f 72 74 20 61 75 74 6f 2d  ot support auto-
5fa0: 76 61 63 75 75 6d 2e 0a 0a 4e 75 6d 62 65 72 20  vacuum...Number 
5fb0: 6f 66 20 74 61 62 6c 65 73 20 69 6e 20 74 68 65  of tables in the
5fc0: 20 64 61 74 61 62 61 73 65 0a 0a 20 20 20 20 54   database..    T
5fd0: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 74 61 62  he number of tab
5fe0: 6c 65 73 20 69 6e 20 74 68 65 20 64 61 74 61 62  les in the datab
5ff0: 61 73 65 2c 20 69 6e 63 6c 75 64 69 6e 67 20 74  ase, including t
6000: 68 65 20 53 51 4c 49 54 45 5f 4d 41 53 54 45 52  he SQLITE_MASTER
6010: 20 74 61 62 6c 65 0a 20 20 20 20 75 73 65 64 20   table.    used 
6020: 74 6f 20 73 74 6f 72 65 20 73 63 68 65 6d 61 20  to store schema 
6030: 69 6e 66 6f 72 6d 61 74 69 6f 6e 2e 0a 0a 4e 75  information...Nu
6040: 6d 62 65 72 20 6f 66 20 69 6e 64 69 63 65 73 0a  mber of indices.
6050: 0a 20 20 20 20 54 68 65 20 74 6f 74 61 6c 20 6e  .    The total n
6060: 75 6d 62 65 72 20 6f 66 20 69 6e 64 69 63 65 73  umber of indices
6070: 20 69 6e 20 74 68 65 20 64 61 74 61 62 61 73 65   in the database
6080: 2e 0a 0a 4e 75 6d 62 65 72 20 6f 66 20 6e 61 6d  ...Number of nam
6090: 65 64 20 69 6e 64 69 63 65 73 0a 0a 20 20 20 20  ed indices..    
60a0: 54 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 69 6e  The number of in
60b0: 64 69 63 65 73 20 63 72 65 61 74 65 64 20 75 73  dices created us
60c0: 69 6e 67 20 61 6e 20 65 78 70 6c 69 63 69 74 20  ing an explicit 
60d0: 43 52 45 41 54 45 20 49 4e 44 45 58 20 73 74 61  CREATE INDEX sta
60e0: 74 65 6d 65 6e 74 2e 0a 0a 41 75 74 6f 6d 61 74  tement...Automat
60f0: 69 63 61 6c 6c 79 20 67 65 6e 65 72 61 74 65 64  ically generated
6100: 20 69 6e 64 69 63 65 73 0a 0a 20 20 20 20 54 68   indices..    Th
6110: 65 20 6e 75 6d 62 65 72 20 6f 66 20 69 6e 64 69  e number of indi
6120: 63 65 73 20 75 73 65 64 20 74 6f 20 69 6d 70 6c  ces used to impl
6130: 65 6d 65 6e 74 20 50 52 49 4d 41 52 59 20 4b 45  ement PRIMARY KE
6140: 59 20 6f 72 20 55 4e 49 51 55 45 20 63 6f 6e 73  Y or UNIQUE cons
6150: 74 72 61 69 6e 74 73 0a 20 20 20 20 6f 6e 20 74  traints.    on t
6160: 61 62 6c 65 73 2e 0a 0a 53 69 7a 65 20 6f 66 20  ables...Size of 
6170: 74 68 65 20 66 69 6c 65 20 69 6e 20 62 79 74 65  the file in byte
6180: 73 0a 0a 20 20 20 20 54 68 65 20 74 6f 74 61 6c  s..    The total
6190: 20 61 6d 6f 75 6e 74 20 6f 66 20 64 69 73 6b 20   amount of disk 
61a0: 73 70 61 63 65 20 75 73 65 64 20 62 79 20 74 68  space used by th
61b0: 65 20 65 6e 74 69 72 65 20 64 61 74 61 62 61 73  e entire databas
61c0: 65 20 66 69 6c 65 73 2e 0a 0a 42 79 74 65 73 20  e files...Bytes 
61d0: 6f 66 20 75 73 65 72 20 70 61 79 6c 6f 61 64 20  of user payload 
61e0: 73 74 6f 72 65 64 0a 0a 20 20 20 20 54 68 65 20  stored..    The 
61f0: 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20  total number of 
6200: 62 79 74 65 73 20 6f 66 20 75 73 65 72 20 70 61  bytes of user pa
6210: 79 6c 6f 61 64 20 73 74 6f 72 65 64 20 69 6e 20  yload stored in 
6220: 74 68 65 20 64 61 74 61 62 61 73 65 2e 20 54 68  the database. Th
6230: 65 0a 20 20 20 20 73 63 68 65 6d 61 20 69 6e 66  e.    schema inf
6240: 6f 72 6d 61 74 69 6f 6e 20 69 6e 20 74 68 65 20  ormation in the 
6250: 53 51 4c 49 54 45 5f 4d 41 53 54 45 52 20 74 61  SQLITE_MASTER ta
6260: 62 6c 65 20 69 73 20 6e 6f 74 20 63 6f 75 6e 74  ble is not count
6270: 65 64 20 77 68 65 6e 0a 20 20 20 20 63 6f 6d 70  ed when.    comp
6280: 75 74 69 6e 67 20 74 68 69 73 20 6e 75 6d 62 65  uting this numbe
6290: 72 2e 20 20 54 68 65 20 70 65 72 63 65 6e 74 61  r.  The percenta
62a0: 67 65 20 61 74 20 74 68 65 20 72 69 67 68 74 20  ge at the right 
62b0: 73 68 6f 77 73 20 74 68 65 20 70 61 79 6c 6f 61  shows the payloa
62c0: 64 0a 20 20 20 20 64 69 76 69 64 65 64 20 62 79  d.    divided by
62d0: 20 74 68 65 20 74 6f 74 61 6c 20 66 69 6c 65 20   the total file 
62e0: 73 69 7a 65 2e 0a 0a 50 65 72 63 65 6e 74 61 67  size...Percentag
62f0: 65 20 6f 66 20 74 6f 74 61 6c 20 64 61 74 61 62  e of total datab
6300: 61 73 65 0a 0a 20 20 20 20 54 68 65 20 61 6d 6f  ase..    The amo
6310: 75 6e 74 20 6f 66 20 74 68 65 20 63 6f 6d 70 6c  unt of the compl
6320: 65 74 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  ete database fil
6330: 65 20 74 68 61 74 20 69 73 20 64 65 76 6f 74 65  e that is devote
6340: 64 20 74 6f 20 73 74 6f 72 69 6e 67 0a 20 20 20  d to storing.   
6350: 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 64 65 73   information des
6360: 63 72 69 62 65 64 20 62 79 20 74 68 69 73 20 63  cribed by this c
6370: 61 74 65 67 6f 72 79 2e 0a 0a 4e 75 6d 62 65 72  ategory...Number
6380: 20 6f 66 20 65 6e 74 72 69 65 73 0a 0a 20 20 20   of entries..   
6390: 20 54 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65   The total numbe
63a0: 72 20 6f 66 20 42 2d 54 72 65 65 20 6b 65 79 2f  r of B-Tree key/
63b0: 76 61 6c 75 65 20 70 61 69 72 73 20 73 74 6f 72  value pairs stor
63c0: 65 64 20 75 6e 64 65 72 20 74 68 69 73 20 63 61  ed under this ca
63d0: 74 65 67 6f 72 79 2e 0a 0a 42 79 74 65 73 20 6f  tegory...Bytes o
63e0: 66 20 73 74 6f 72 61 67 65 20 63 6f 6e 73 75 6d  f storage consum
63f0: 65 64 0a 0a 20 20 20 20 54 68 65 20 74 6f 74 61  ed..    The tota
6400: 6c 20 61 6d 6f 75 6e 74 20 6f 66 20 64 69 73 6b  l amount of disk
6410: 20 73 70 61 63 65 20 72 65 71 75 69 72 65 64 20   space required 
6420: 74 6f 20 73 74 6f 72 65 20 61 6c 6c 20 42 2d 54  to store all B-T
6430: 72 65 65 20 65 6e 74 72 69 65 73 0a 20 20 20 20  ree entries.    
6440: 75 6e 64 65 72 20 74 68 69 73 20 63 61 74 65 67  under this categ
6450: 6f 72 79 2e 20 20 54 68 65 20 69 73 20 74 68 65  ory.  The is the
6460: 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66   total number of
6470: 20 70 61 67 65 73 20 75 73 65 64 20 74 69 6d 65   pages used time
6480: 73 0a 20 20 20 20 74 68 65 20 70 61 67 65 73 20  s.    the pages 
6490: 73 69 7a 65 2e 0a 0a 42 79 74 65 73 20 6f 66 20  size...Bytes of 
64a0: 70 61 79 6c 6f 61 64 0a 0a 20 20 20 20 54 68 65  payload..    The
64b0: 20 61 6d 6f 75 6e 74 20 6f 66 20 70 61 79 6c 6f   amount of paylo
64c0: 61 64 20 73 74 6f 72 65 64 20 75 6e 64 65 72 20  ad stored under 
64d0: 74 68 69 73 20 63 61 74 65 67 6f 72 79 2e 20 20  this category.  
64e0: 50 61 79 6c 6f 61 64 20 69 73 20 74 68 65 20 64  Payload is the d
64f0: 61 74 61 0a 20 20 20 20 70 61 72 74 20 6f 66 20  ata.    part of 
6500: 74 61 62 6c 65 20 65 6e 74 72 69 65 73 20 61 6e  table entries an
6510: 64 20 74 68 65 20 6b 65 79 20 70 61 72 74 20 6f  d the key part o
6520: 66 20 69 6e 64 65 78 20 65 6e 74 72 69 65 73 2e  f index entries.
6530: 20 20 54 68 65 20 70 65 72 63 65 6e 74 61 67 65    The percentage
6540: 0a 20 20 20 20 61 74 20 74 68 65 20 72 69 67 68  .    at the righ
6550: 74 20 69 73 20 74 68 65 20 62 79 74 65 73 20 6f  t is the bytes o
6560: 66 20 70 61 79 6c 6f 61 64 20 64 69 76 69 64 65  f payload divide
6570: 64 20 62 79 20 74 68 65 20 62 79 74 65 73 20 6f  d by the bytes o
6580: 66 20 73 74 6f 72 61 67 65 20 0a 20 20 20 20 63  f storage .    c
6590: 6f 6e 73 75 6d 65 64 2e 0a 0a 41 76 65 72 61 67  onsumed...Averag
65a0: 65 20 70 61 79 6c 6f 61 64 20 70 65 72 20 65 6e  e payload per en
65b0: 74 72 79 0a 0a 20 20 20 20 54 68 65 20 61 76 65  try..    The ave
65c0: 72 61 67 65 20 61 6d 6f 75 6e 74 20 6f 66 20 70  rage amount of p
65d0: 61 79 6c 6f 61 64 20 6f 6e 20 65 61 63 68 20 65  ayload on each e
65e0: 6e 74 72 79 2e 20 20 54 68 69 73 20 69 73 20 6a  ntry.  This is j
65f0: 75 73 74 20 74 68 65 20 62 79 74 65 73 20 6f 66  ust the bytes of
6600: 0a 20 20 20 20 70 61 79 6c 6f 61 64 20 64 69 76  .    payload div
6610: 69 64 65 64 20 62 79 20 74 68 65 20 6e 75 6d 62  ided by the numb
6620: 65 72 20 6f 66 20 65 6e 74 72 69 65 73 2e 0a 0a  er of entries...
6630: 41 76 65 72 61 67 65 20 75 6e 75 73 65 64 20 62  Average unused b
6640: 79 74 65 73 20 70 65 72 20 65 6e 74 72 79 0a 0a  ytes per entry..
6650: 20 20 20 20 54 68 65 20 61 76 65 72 61 67 65 20      The average 
6660: 61 6d 6f 75 6e 74 20 6f 66 20 66 72 65 65 20 73  amount of free s
6670: 70 61 63 65 20 72 65 6d 61 69 6e 69 6e 67 20 6f  pace remaining o
6680: 6e 20 61 6c 6c 20 70 61 67 65 73 20 75 6e 64 65  n all pages unde
6690: 72 20 74 68 69 73 0a 20 20 20 20 63 61 74 65 67  r this.    categ
66a0: 6f 72 79 20 6f 6e 20 61 20 70 65 72 2d 65 6e 74  ory on a per-ent
66b0: 72 79 20 62 61 73 69 73 2e 20 20 54 68 69 73 20  ry basis.  This 
66c0: 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  is the number of
66d0: 20 75 6e 75 73 65 64 20 62 79 74 65 73 20 6f 6e   unused bytes on
66e0: 0a 20 20 20 20 61 6c 6c 20 70 61 67 65 73 20 64  .    all pages d
66f0: 69 76 69 64 65 64 20 62 79 20 74 68 65 20 6e 75  ivided by the nu
6700: 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73 2e  mber of entries.
6710: 0a 0a 4d 61 78 69 6d 75 6d 20 70 61 79 6c 6f 61  ..Maximum payloa
6720: 64 20 70 65 72 20 65 6e 74 72 79 0a 0a 20 20 20  d per entry..   
6730: 20 54 68 65 20 6c 61 72 67 65 73 74 20 70 61 79   The largest pay
6740: 6c 6f 61 64 20 73 69 7a 65 20 6f 66 20 61 6e 79  load size of any
6750: 20 65 6e 74 72 79 2e 0a 0a 45 6e 74 72 69 65 73   entry...Entries
6760: 20 74 68 61 74 20 75 73 65 20 6f 76 65 72 66 6c   that use overfl
6770: 6f 77 0a 0a 20 20 20 20 54 68 65 20 6e 75 6d 62  ow..    The numb
6780: 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20 74 68  er of entries th
6790: 61 74 20 75 73 65 72 20 6f 6e 65 20 6f 72 20 6d  at user one or m
67a0: 6f 72 65 20 6f 76 65 72 66 6c 6f 77 20 70 61 67  ore overflow pag
67b0: 65 73 2e 0a 0a 54 6f 74 61 6c 20 70 61 67 65 73  es...Total pages
67c0: 20 75 73 65 64 0a 0a 20 20 20 20 54 68 69 73 20   used..    This 
67d0: 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  is the number of
67e0: 20 70 61 67 65 73 20 75 73 65 64 20 74 6f 20 68   pages used to h
67f0: 6f 6c 64 20 61 6c 6c 20 69 6e 66 6f 72 6d 61 74  old all informat
6800: 69 6f 6e 20 69 6e 20 74 68 65 20 63 75 72 72 65  ion in the curre
6810: 6e 74 0a 20 20 20 20 63 61 74 65 67 6f 72 79 2e  nt.    category.
6820: 20 20 54 68 69 73 20 69 73 20 74 68 65 20 73 75    This is the su
6830: 6d 20 6f 66 20 69 6e 64 65 78 2c 20 70 72 69 6d  m of index, prim
6840: 61 72 79 2c 20 61 6e 64 20 6f 76 65 72 66 6c 6f  ary, and overflo
6850: 77 20 70 61 67 65 73 2e 0a 0a 49 6e 64 65 78 20  w pages...Index 
6860: 70 61 67 65 73 20 75 73 65 64 0a 0a 20 20 20 20  pages used..    
6870: 54 68 69 73 20 69 73 20 74 68 65 20 6e 75 6d 62  This is the numb
6880: 65 72 20 6f 66 20 70 61 67 65 73 20 69 6e 20 61  er of pages in a
6890: 20 74 61 62 6c 65 20 42 2d 74 72 65 65 20 74 68   table B-tree th
68a0: 61 74 20 68 6f 6c 64 20 6f 6e 6c 79 20 6b 65 79  at hold only key
68b0: 20 28 72 6f 77 69 64 29 0a 20 20 20 20 69 6e 66   (rowid).    inf
68c0: 6f 72 6d 61 74 69 6f 6e 20 61 6e 64 20 6e 6f 20  ormation and no 
68d0: 64 61 74 61 2e 0a 0a 50 72 69 6d 61 72 79 20 70  data...Primary p
68e0: 61 67 65 73 20 75 73 65 64 0a 0a 20 20 20 20 54  ages used..    T
68f0: 68 69 73 20 69 73 20 74 68 65 20 6e 75 6d 62 65  his is the numbe
6900: 72 20 6f 66 20 42 2d 74 72 65 65 20 70 61 67 65  r of B-tree page
6910: 73 20 74 68 61 74 20 68 6f 6c 64 20 62 6f 74 68  s that hold both
6920: 20 6b 65 79 20 61 6e 64 20 64 61 74 61 2e 0a 0a   key and data...
6930: 4f 76 65 72 66 6c 6f 77 20 70 61 67 65 73 20 75  Overflow pages u
6940: 73 65 64 0a 0a 20 20 20 20 54 68 65 20 74 6f 74  sed..    The tot
6950: 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 6f 76 65  al number of ove
6960: 72 66 6c 6f 77 20 70 61 67 65 73 20 75 73 65 64  rflow pages used
6970: 20 66 6f 72 20 74 68 69 73 20 63 61 74 65 67 6f   for this catego
6980: 72 79 2e 0a 0a 55 6e 75 73 65 64 20 62 79 74 65  ry...Unused byte
6990: 73 20 6f 6e 20 69 6e 64 65 78 20 70 61 67 65 73  s on index pages
69a0: 0a 0a 20 20 20 20 54 68 65 20 74 6f 74 61 6c 20  ..    The total 
69b0: 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  number of bytes 
69c0: 6f 66 20 75 6e 75 73 65 64 20 73 70 61 63 65 20  of unused space 
69d0: 6f 6e 20 61 6c 6c 20 69 6e 64 65 78 20 70 61 67  on all index pag
69e0: 65 73 2e 20 20 54 68 65 0a 20 20 20 20 70 65 72  es.  The.    per
69f0: 63 65 6e 74 61 67 65 20 61 74 20 74 68 65 20 72  centage at the r
6a00: 69 67 68 74 20 69 73 20 74 68 65 20 6e 75 6d 62  ight is the numb
6a10: 65 72 20 6f 66 20 75 6e 75 73 65 64 20 62 79 74  er of unused byt
6a20: 65 73 20 64 69 76 69 64 65 64 20 62 79 20 74 68  es divided by th
6a30: 65 0a 20 20 20 20 74 6f 74 61 6c 20 6e 75 6d 62  e.    total numb
6a40: 65 72 20 6f 66 20 62 79 74 65 73 20 6f 6e 20 69  er of bytes on i
6a50: 6e 64 65 78 20 70 61 67 65 73 2e 0a 0a 55 6e 75  ndex pages...Unu
6a60: 73 65 64 20 62 79 74 65 73 20 6f 6e 20 70 72 69  sed bytes on pri
6a70: 6d 61 72 79 20 70 61 67 65 73 0a 0a 20 20 20 20  mary pages..    
6a80: 54 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72  The total number
6a90: 20 6f 66 20 62 79 74 65 73 20 6f 66 20 75 6e 75   of bytes of unu
6aa0: 73 65 64 20 73 70 61 63 65 20 6f 6e 20 61 6c 6c  sed space on all
6ab0: 20 70 72 69 6d 61 72 79 20 70 61 67 65 73 2e 20   primary pages. 
6ac0: 20 54 68 65 0a 20 20 20 20 70 65 72 63 65 6e 74   The.    percent
6ad0: 61 67 65 20 61 74 20 74 68 65 20 72 69 67 68 74  age at the right
6ae0: 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f   is the number o
6af0: 66 20 75 6e 75 73 65 64 20 62 79 74 65 73 20 64  f unused bytes d
6b00: 69 76 69 64 65 64 20 62 79 20 74 68 65 0a 20 20  ivided by the.  
6b10: 20 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f    total number o
6b20: 66 20 62 79 74 65 73 20 6f 6e 20 70 72 69 6d 61  f bytes on prima
6b30: 72 79 20 70 61 67 65 73 2e 0a 0a 55 6e 75 73 65  ry pages...Unuse
6b40: 64 20 62 79 74 65 73 20 6f 6e 20 6f 76 65 72 66  d bytes on overf
6b50: 6c 6f 77 20 70 61 67 65 73 0a 0a 20 20 20 20 54  low pages..    T
6b60: 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20  he total number 
6b70: 6f 66 20 62 79 74 65 73 20 6f 66 20 75 6e 75 73  of bytes of unus
6b80: 65 64 20 73 70 61 63 65 20 6f 6e 20 61 6c 6c 20  ed space on all 
6b90: 6f 76 65 72 66 6c 6f 77 20 70 61 67 65 73 2e 20  overflow pages. 
6ba0: 20 54 68 65 0a 20 20 20 20 70 65 72 63 65 6e 74   The.    percent
6bb0: 61 67 65 20 61 74 20 74 68 65 20 72 69 67 68 74  age at the right
6bc0: 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f   is the number o
6bd0: 66 20 75 6e 75 73 65 64 20 62 79 74 65 73 20 64  f unused bytes d
6be0: 69 76 69 64 65 64 20 62 79 20 74 68 65 0a 20 20  ivided by the.  
6bf0: 20 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f    total number o
6c00: 66 20 62 79 74 65 73 20 6f 6e 20 6f 76 65 72 66  f bytes on overf
6c10: 6c 6f 77 20 70 61 67 65 73 2e 0a 0a 55 6e 75 73  low pages...Unus
6c20: 65 64 20 62 79 74 65 73 20 6f 6e 20 61 6c 6c 20  ed bytes on all 
6c30: 70 61 67 65 73 0a 0a 20 20 20 20 54 68 65 20 74  pages..    The t
6c40: 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 62  otal number of b
6c50: 79 74 65 73 20 6f 66 20 75 6e 75 73 65 64 20 73  ytes of unused s
6c60: 70 61 63 65 20 6f 6e 20 61 6c 6c 20 70 72 69 6d  pace on all prim
6c70: 61 72 79 20 61 6e 64 20 6f 76 65 72 66 6c 6f 77  ary and overflow
6c80: 20 0a 20 20 20 20 70 61 67 65 73 2e 20 20 54 68   .    pages.  Th
6c90: 65 20 70 65 72 63 65 6e 74 61 67 65 20 61 74 20  e percentage at 
6ca0: 74 68 65 20 72 69 67 68 74 20 69 73 20 74 68 65  the right is the
6cb0: 20 6e 75 6d 62 65 72 20 6f 66 20 75 6e 75 73 65   number of unuse
6cc0: 64 20 62 79 74 65 73 20 0a 20 20 20 20 64 69 76  d bytes .    div
6cd0: 69 64 65 64 20 62 79 20 74 68 65 20 74 6f 74 61  ided by the tota
6ce0: 6c 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65  l number of byte
6cf0: 73 2e 0a 7d 0a 0a 23 20 4f 75 74 70 75 74 20 61  s..}..# Output a
6d00: 20 64 75 6d 70 20 6f 66 20 74 68 65 20 69 6e 2d   dump of the in-
6d10: 6d 65 6d 6f 72 79 20 64 61 74 61 62 61 73 65 2e  memory database.
6d20: 20 54 68 69 73 20 63 61 6e 20 62 65 20 75 73 65   This can be use
6d30: 64 20 66 6f 72 20 6d 6f 72 65 0a 23 20 63 6f 6d  d for more.# com
6d40: 70 6c 65 78 20 6f 66 66 6c 69 6e 65 20 61 6e 61  plex offline ana
6d50: 6c 79 73 69 73 2e 0a 23 0a 70 75 74 73 20 22 2a  lysis..#.puts "*
6d60: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
6d70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
6d80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
6d90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
6da0: 2a 2a 2a 2a 2a 22 0a 70 75 74 73 20 22 54 68 65  *****".puts "The
6db0: 20 65 6e 74 69 72 65 20 74 65 78 74 20 6f 66 20   entire text of 
6dc0: 74 68 69 73 20 72 65 70 6f 72 74 20 63 61 6e 20  this report can 
6dd0: 62 65 20 73 6f 75 72 63 65 64 20 69 6e 74 6f 20  be sourced into 
6de0: 61 6e 79 20 53 51 4c 20 64 61 74 61 62 61 73 65  any SQL database
6df0: 22 0a 70 75 74 73 20 22 65 6e 67 69 6e 65 20 66  ".puts "engine f
6e00: 6f 72 20 66 75 72 74 68 65 72 20 61 6e 61 6c 79  or further analy
6e10: 73 69 73 2e 20 20 41 6c 6c 20 6f 66 20 74 68 65  sis.  All of the
6e20: 20 74 65 78 74 20 61 62 6f 76 65 20 69 73 20 61   text above is a
6e30: 6e 20 53 51 4c 20 63 6f 6d 6d 65 6e 74 2e 22 0a  n SQL comment.".
6e40: 70 75 74 73 20 22 54 68 65 20 64 61 74 61 20 75  puts "The data u
6e50: 73 65 64 20 74 6f 20 67 65 6e 65 72 61 74 65 20  sed to generate 
6e60: 74 68 69 73 20 72 65 70 6f 72 74 20 66 6f 6c 6c  this report foll
6e70: 6f 77 73 3a 22 0a 70 75 74 73 20 22 2a 2f 22 0a  ows:".puts "*/".
6e80: 70 75 74 73 20 22 42 45 47 49 4e 3b 22 0a 70 75  puts "BEGIN;".pu
6e90: 74 73 20 24 74 61 62 6c 65 64 65 66 0a 75 6e 73  ts $tabledef.uns
6ea0: 65 74 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 78  et -nocomplain x
6eb0: 0a 6d 65 6d 20 65 76 61 6c 20 7b 53 45 4c 45 43  .mem eval {SELEC
6ec0: 54 20 2a 20 46 52 4f 4d 20 73 70 61 63 65 5f 75  T * FROM space_u
6ed0: 73 65 64 7d 20 78 20 7b 0a 20 20 70 75 74 73 20  sed} x {.  puts 
6ee0: 2d 6e 6f 6e 65 77 6c 69 6e 65 20 22 49 4e 53 45  -nonewline "INSE
6ef0: 52 54 20 49 4e 54 4f 20 73 70 61 63 65 5f 75 73  RT INTO space_us
6f00: 65 64 20 56 41 4c 55 45 53 22 0a 20 20 73 65 74  ed VALUES".  set
6f10: 20 73 65 70 20 28 0a 20 20 66 6f 72 65 61 63 68   sep (.  foreach
6f20: 20 63 6f 6c 20 24 78 28 2a 29 20 7b 0a 20 20 20   col $x(*) {.   
6f30: 20 73 65 74 20 76 20 24 78 28 24 63 6f 6c 29 0a   set v $x($col).
6f40: 20 20 20 20 69 66 20 7b 24 76 3d 3d 22 22 20 7c      if {$v=="" |
6f50: 7c 20 21 5b 73 74 72 69 6e 67 20 69 73 20 64 6f  | ![string is do
6f60: 75 62 6c 65 20 24 76 5d 7d 20 7b 73 65 74 20 76  uble $v]} {set v
6f70: 20 5b 71 75 6f 74 65 20 24 76 5d 7d 0a 20 20 20   [quote $v]}.   
6f80: 20 70 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65   puts -nonewline
6f90: 20 24 73 65 70 24 76 0a 20 20 20 20 73 65 74 20   $sep$v.    set 
6fa0: 73 65 70 20 2c 0a 20 20 7d 0a 20 20 70 75 74 73  sep ,.  }.  puts
6fb0: 20 22 29 3b 22 0a 7d 0a 70 75 74 73 20 22 43 4f   ");".}.puts "CO
6fc0: 4d 4d 49 54 3b 22 0a                             MMIT;".