/ Hex Artifact Content
Login

Artifact f4ca4843c137db16124d680523f466044d5f0ba2:


0000: 23 20 52 75 6e 20 74 68 69 73 20 54 43 4c 20 73  # Run this TCL s
0010: 63 72 69 70 74 20 75 73 69 6e 67 20 22 74 65 73  cript using "tes
0020: 74 66 69 78 74 75 72 65 22 20 69 6e 20 6f 72 64  tfixture" in ord
0030: 65 72 20 67 65 74 20 61 20 72 65 70 6f 72 74 20  er get a report 
0040: 74 68 61 74 20 73 68 6f 77 73 0a 23 20 68 6f 77  that shows.# how
0050: 20 6d 75 63 68 20 64 69 73 6b 20 73 70 61 63 65   much disk space
0060: 20 69 73 20 75 73 65 64 20 62 79 20 61 20 70 61   is used by a pa
0070: 72 74 69 63 75 6c 61 72 20 64 61 74 61 20 74 6f  rticular data to
0080: 20 61 63 74 75 61 6c 6c 79 20 73 74 6f 72 65 20   actually store 
0090: 64 61 74 61 0a 23 20 76 65 72 73 75 73 20 68 6f  data.# versus ho
00a0: 77 20 6d 75 63 68 20 73 70 61 63 65 20 69 73 20  w much space is 
00b0: 75 6e 75 73 65 64 2e 0a 23 0a 0a 69 66 20 7b 5b  unused..#..if {[
00c0: 63 61 74 63 68 20 7b 0a 0a 23 20 47 65 74 20 74  catch {..# Get t
00d0: 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 64  he name of the d
00e0: 61 74 61 62 61 73 65 20 74 6f 20 61 6e 61 6c 79  atabase to analy
00f0: 7a 65 0a 23 0a 23 73 65 74 20 61 72 67 76 20 24  ze.#.#set argv $
0100: 61 72 67 76 30 0a 69 66 20 7b 5b 6c 6c 65 6e 67  argv0.if {[lleng
0110: 74 68 20 24 61 72 67 76 5d 21 3d 31 7d 20 7b 0a  th $argv]!=1} {.
0120: 20 20 70 75 74 73 20 73 74 64 65 72 72 20 22 55    puts stderr "U
0130: 73 61 67 65 3a 20 24 61 72 67 76 30 20 64 61 74  sage: $argv0 dat
0140: 61 62 61 73 65 2d 6e 61 6d 65 22 0a 20 20 65 78  abase-name".  ex
0150: 69 74 20 31 0a 7d 0a 73 65 74 20 66 69 6c 65 5f  it 1.}.set file_
0160: 74 6f 5f 61 6e 61 6c 79 7a 65 20 5b 6c 69 6e 64  to_analyze [lind
0170: 65 78 20 24 61 72 67 76 20 30 5d 0a 69 66 20 7b  ex $argv 0].if {
0180: 21 5b 66 69 6c 65 20 65 78 69 73 74 73 20 24 66  ![file exists $f
0190: 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 5d 7d  ile_to_analyze]}
01a0: 20 7b 0a 20 20 70 75 74 73 20 73 74 64 65 72 72   {.  puts stderr
01b0: 20 22 4e 6f 20 73 75 63 68 20 66 69 6c 65 3a 20   "No such file: 
01c0: 24 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65  $file_to_analyze
01d0: 22 0a 20 20 65 78 69 74 20 31 0a 7d 0a 69 66 20  ".  exit 1.}.if 
01e0: 7b 21 5b 66 69 6c 65 20 72 65 61 64 61 62 6c 65  {![file readable
01f0: 20 24 66 69 6c 65 5f 74 6f 5f 61 6e 61 6c 79 7a   $file_to_analyz
0200: 65 5d 7d 20 7b 0a 20 20 70 75 74 73 20 73 74 64  e]} {.  puts std
0210: 65 72 72 20 22 46 69 6c 65 20 69 73 20 6e 6f 74  err "File is not
0220: 20 72 65 61 64 61 62 6c 65 3a 20 24 66 69 6c 65   readable: $file
0230: 5f 74 6f 5f 61 6e 61 6c 79 7a 65 22 0a 20 20 65  _to_analyze".  e
0240: 78 69 74 20 31 0a 7d 0a 69 66 20 7b 5b 66 69 6c  xit 1.}.if {[fil
0250: 65 20 73 69 7a 65 20 24 66 69 6c 65 5f 74 6f 5f  e size $file_to_
0260: 61 6e 61 6c 79 7a 65 5d 3c 35 31 32 7d 20 7b 0a  analyze]<512} {.
0270: 20 20 70 75 74 73 20 73 74 64 65 72 72 20 22 45    puts stderr "E
0280: 6d 70 74 79 20 6f 72 20 6d 61 6c 66 6f 72 6d 65  mpty or malforme
0290: 64 20 64 61 74 61 62 61 73 65 3a 20 24 66 69 6c  d database: $fil
02a0: 65 5f 74 6f 5f 61 6e 61 6c 79 7a 65 22 0a 20 20  e_to_analyze".  
02b0: 65 78 69 74 20 31 0a 7d 0a 0a 23 20 4f 70 65 6e  exit 1.}..# Open
02c0: 20 74 68 65 20 64 61 74 61 62 61 73 65 0a 23 0a   the database.#.
02d0: 73 71 6c 69 74 65 33 20 64 62 20 5b 6c 69 6e 64  sqlite3 db [lind
02e0: 65 78 20 24 61 72 67 76 20 30 5d 0a 73 65 74 20  ex $argv 0].set 
02f0: 44 42 20 5b 62 74 72 65 65 5f 6f 70 65 6e 20 5b  DB [btree_open [
0300: 6c 69 6e 64 65 78 20 24 61 72 67 76 20 30 5d 20  lindex $argv 0] 
0310: 31 30 30 30 20 30 5d 0a 0a 23 20 49 6e 2d 6d 65  1000 0]..# In-me
0320: 6d 6f 72 79 20 64 61 74 61 62 61 73 65 20 66 6f  mory database fo
0330: 72 20 63 6f 6c 6c 65 63 74 69 6e 67 20 73 74 61  r collecting sta
0340: 74 69 73 74 69 63 73 2e 20 54 68 69 73 20 73 63  tistics. This sc
0350: 72 69 70 74 20 6c 6f 6f 70 73 20 74 68 72 6f 75  ript loops throu
0360: 67 68 0a 23 20 74 68 65 20 74 61 62 6c 65 73 20  gh.# the tables 
0370: 61 6e 64 20 69 6e 64 69 63 65 73 20 69 6e 20 74  and indices in t
0380: 68 65 20 64 61 74 61 62 61 73 65 20 62 65 69 6e  he database bein
0390: 67 20 61 6e 61 6c 79 7a 65 64 2c 20 61 64 64 69  g analyzed, addi
03a0: 6e 67 20 61 20 72 6f 77 20 66 6f 72 20 65 61 63  ng a row for eac
03b0: 68 0a 23 20 74 6f 20 61 6e 20 69 6e 2d 6d 65 6d  h.# to an in-mem
03c0: 6f 72 79 20 64 61 74 61 62 61 73 65 20 28 66 6f  ory database (fo
03d0: 72 20 77 68 69 63 68 20 74 68 65 20 73 63 68 65  r which the sche
03e0: 6d 61 20 69 73 20 73 68 6f 77 6e 20 62 65 6c 6f  ma is shown belo
03f0: 77 29 2e 20 49 74 20 74 68 65 6e 0a 23 20 71 75  w). It then.# qu
0400: 65 72 69 65 73 20 74 68 65 20 69 6e 2d 6d 65 6d  eries the in-mem
0410: 6f 72 79 20 64 62 20 74 6f 20 70 72 6f 64 75 63  ory db to produc
0420: 65 20 74 68 65 20 73 70 61 63 65 2d 61 6e 61 6c  e the space-anal
0430: 79 73 69 73 20 72 65 70 6f 72 74 2e 0a 23 0a 73  ysis report..#.s
0440: 71 6c 69 74 65 33 20 6d 65 6d 20 3a 6d 65 6d 6f  qlite3 mem :memo
0450: 72 79 3a 0a 73 65 74 20 74 61 62 6c 65 64 65 66  ry:.set tabledef
0460: 5c 0a 7b 43 52 45 41 54 45 20 54 41 42 4c 45 20  \.{CREATE TABLE 
0470: 73 70 61 63 65 5f 75 73 65 64 28 0a 20 20 20 6e  space_used(.   n
0480: 61 6d 65 20 63 6c 6f 62 2c 20 20 20 20 20 20 20  ame clob,       
0490: 20 2d 2d 20 4e 61 6d 65 20 6f 66 20 61 20 74 61   -- Name of a ta
04a0: 62 6c 65 20 6f 72 20 69 6e 64 65 78 20 69 6e 20  ble or index in 
04b0: 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
04c0: 65 0a 20 20 20 74 62 6c 6e 61 6d 65 20 63 6c 6f  e.   tblname clo
04d0: 62 2c 20 20 20 20 20 2d 2d 20 4e 61 6d 65 20 6f  b,     -- Name o
04e0: 66 20 61 73 73 6f 63 69 61 74 65 64 20 74 61 62  f associated tab
04f0: 6c 65 0a 20 20 20 69 73 5f 69 6e 64 65 78 20 62  le.   is_index b
0500: 6f 6f 6c 65 61 6e 2c 20 2d 2d 20 54 52 55 45 20  oolean, -- TRUE 
0510: 69 66 20 69 74 20 69 73 20 61 6e 20 69 6e 64 65  if it is an inde
0520: 78 2c 20 66 61 6c 73 65 20 66 6f 72 20 61 20 74  x, false for a t
0530: 61 62 6c 65 0a 20 20 20 6e 65 6e 74 72 79 20 69  able.   nentry i
0540: 6e 74 2c 20 20 20 20 20 20 20 2d 2d 20 4e 75 6d  nt,       -- Num
0550: 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20 69  ber of entries i
0560: 6e 20 74 68 65 20 42 54 72 65 65 0a 20 20 20 6c  n the BTree.   l
0570: 65 61 66 5f 65 6e 74 72 69 65 73 20 69 6e 74 2c  eaf_entries int,
0580: 20 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20 6c 65   -- Number of le
0590: 61 66 20 65 6e 74 72 69 65 73 0a 20 20 20 70 61  af entries.   pa
05a0: 79 6c 6f 61 64 20 69 6e 74 2c 20 20 20 20 20 20  yload int,      
05b0: 2d 2d 20 54 6f 74 61 6c 20 61 6d 6f 75 6e 74 20  -- Total amount 
05c0: 6f 66 20 64 61 74 61 20 73 74 6f 72 65 64 20 69  of data stored i
05d0: 6e 20 74 68 69 73 20 74 61 62 6c 65 20 6f 72 20  n this table or 
05e0: 69 6e 64 65 78 0a 20 20 20 6f 76 66 6c 5f 70 61  index.   ovfl_pa
05f0: 79 6c 6f 61 64 20 69 6e 74 2c 20 2d 2d 20 54 6f  yload int, -- To
0600: 74 61 6c 20 61 6d 6f 75 6e 74 20 6f 66 20 64 61  tal amount of da
0610: 74 61 20 73 74 6f 72 65 64 20 6f 6e 20 6f 76 65  ta stored on ove
0620: 72 66 6c 6f 77 20 70 61 67 65 73 0a 20 20 20 6f  rflow pages.   o
0630: 76 66 6c 5f 63 6e 74 20 69 6e 74 2c 20 20 20 20  vfl_cnt int,    
0640: 20 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20 65 6e   -- Number of en
0650: 74 72 69 65 73 20 74 68 61 74 20 75 73 65 20 6f  tries that use o
0660: 76 65 72 66 6c 6f 77 0a 20 20 20 6d 78 5f 70 61  verflow.   mx_pa
0670: 79 6c 6f 61 64 20 69 6e 74 2c 20 20 20 2d 2d 20  yload int,   -- 
0680: 4d 61 78 69 6d 75 6d 20 70 61 79 6c 6f 61 64 20  Maximum payload 
0690: 73 69 7a 65 0a 20 20 20 69 6e 74 5f 70 61 67 65  size.   int_page
06a0: 73 20 69 6e 74 2c 20 20 20 20 2d 2d 20 4e 75 6d  s int,    -- Num
06b0: 62 65 72 20 6f 66 20 69 6e 74 65 72 69 6f 72 20  ber of interior 
06c0: 70 61 67 65 73 20 75 73 65 64 0a 20 20 20 6c 65  pages used.   le
06d0: 61 66 5f 70 61 67 65 73 20 69 6e 74 2c 20 20 20  af_pages int,   
06e0: 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20 6c 65 61  -- Number of lea
06f0: 66 20 70 61 67 65 73 20 75 73 65 64 0a 20 20 20  f pages used.   
0700: 6f 76 66 6c 5f 70 61 67 65 73 20 69 6e 74 2c 20  ovfl_pages int, 
0710: 20 20 2d 2d 20 4e 75 6d 62 65 72 20 6f 66 20 6f    -- Number of o
0720: 76 65 72 66 6c 6f 77 20 70 61 67 65 73 20 75 73  verflow pages us
0730: 65 64 0a 20 20 20 69 6e 74 5f 75 6e 75 73 65 64  ed.   int_unused
0740: 20 69 6e 74 2c 20 20 20 2d 2d 20 4e 75 6d 62 65   int,   -- Numbe
0750: 72 20 6f 66 20 75 6e 75 73 65 64 20 62 79 74 65  r of unused byte
0760: 73 20 6f 6e 20 69 6e 74 65 72 69 6f 72 20 70 61  s on interior pa
0770: 67 65 73 0a 20 20 20 6c 65 61 66 5f 75 6e 75 73  ges.   leaf_unus
0780: 65 64 20 69 6e 74 2c 20 20 2d 2d 20 4e 75 6d 62  ed int,  -- Numb
0790: 65 72 20 6f 66 20 75 6e 75 73 65 64 20 62 79 74  er of unused byt
07a0: 65 73 20 6f 6e 20 70 72 69 6d 61 72 79 20 70 61  es on primary pa
07b0: 67 65 73 0a 20 20 20 6f 76 66 6c 5f 75 6e 75 73  ges.   ovfl_unus
07c0: 65 64 20 69 6e 74 20 20 20 2d 2d 20 4e 75 6d 62  ed int   -- Numb
07d0: 65 72 20 6f 66 20 75 6e 75 73 65 64 20 62 79 74  er of unused byt
07e0: 65 73 20 6f 6e 20 6f 76 65 72 66 6c 6f 77 20 70  es on overflow p
07f0: 61 67 65 73 0a 29 3b 7d 0a 6d 65 6d 20 65 76 61  ages.);}.mem eva
0800: 6c 20 24 74 61 62 6c 65 64 65 66 0a 0a 70 72 6f  l $tabledef..pro
0810: 63 20 69 6e 74 65 67 65 72 69 66 79 20 7b 72 65  c integerify {re
0820: 61 6c 7d 20 7b 0a 20 20 72 65 74 75 72 6e 20 5b  al} {.  return [
0830: 65 78 70 72 20 69 6e 74 28 24 72 65 61 6c 29 5d  expr int($real)]
0840: 0a 7d 0a 6d 65 6d 20 66 75 6e 63 74 69 6f 6e 20  .}.mem function 
0850: 69 6e 74 20 69 6e 74 65 67 65 72 69 66 79 0a 0a  int integerify..
0860: 23 20 51 75 6f 74 65 20 61 20 73 74 72 69 6e 67  # Quote a string
0870: 20 66 6f 72 20 75 73 65 20 69 6e 20 61 6e 20 53   for use in an S
0880: 51 4c 20 71 75 65 72 79 2e 20 45 78 61 6d 70 6c  QL query. Exampl
0890: 65 73 3a 0a 23 0a 23 20 5b 71 75 6f 74 65 20 7b  es:.#.# [quote {
08a0: 68 65 6c 6c 6f 20 77 6f 72 6c 64 7d 5d 20 20 20  hello world}]   
08b0: 3d 3d 20 7b 27 68 65 6c 6c 6f 20 77 6f 72 6c 64  == {'hello world
08c0: 27 7d 0a 23 20 5b 71 75 6f 74 65 20 7b 68 65 6c  '}.# [quote {hel
08d0: 6c 6f 20 77 6f 72 6c 64 27 73 7d 5d 20 3d 3d 20  lo world's}] == 
08e0: 7b 27 68 65 6c 6c 6f 20 77 6f 72 6c 64 27 27 73  {'hello world''s
08f0: 27 7d 0a 23 0a 70 72 6f 63 20 71 75 6f 74 65 20  '}.#.proc quote 
0900: 7b 74 78 74 7d 20 7b 0a 20 20 72 65 67 73 75 62  {txt} {.  regsub
0910: 20 2d 61 6c 6c 20 27 20 24 74 78 74 20 27 27 20   -all ' $txt '' 
0920: 71 0a 20 20 72 65 74 75 72 6e 20 27 24 71 27 0a  q.  return '$q'.
0930: 7d 0a 0a 23 20 54 68 69 73 20 70 72 6f 63 20 69  }..# This proc i
0940: 73 20 61 20 77 72 61 70 70 65 72 20 61 72 6f 75  s a wrapper arou
0950: 6e 64 20 74 68 65 20 62 74 72 65 65 5f 63 75 72  nd the btree_cur
0960: 73 6f 72 5f 69 6e 66 6f 20 63 6f 6d 6d 61 6e 64  sor_info command
0970: 2e 20 54 68 65 0a 23 20 73 65 63 6f 6e 64 20 61  . The.# second a
0980: 72 67 75 6d 65 6e 74 20 69 73 20 61 6e 20 6f 70  rgument is an op
0990: 65 6e 20 62 74 72 65 65 20 63 75 72 73 6f 72 20  en btree cursor 
09a0: 72 65 74 75 72 6e 65 64 20 62 79 20 5b 62 74 72  returned by [btr
09b0: 65 65 5f 63 75 72 73 6f 72 5d 2e 0a 23 20 54 68  ee_cursor]..# Th
09c0: 65 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74  e first argument
09d0: 20 69 73 20 74 68 65 20 6e 61 6d 65 20 6f 66 20   is the name of 
09e0: 61 6e 20 61 72 72 61 79 20 76 61 72 69 61 62 6c  an array variabl
09f0: 65 20 74 68 61 74 20 65 78 69 73 74 73 20 69 6e  e that exists in
0a00: 0a 23 20 74 68 65 20 73 63 6f 70 65 20 6f 66 20  .# the scope of 
0a10: 74 68 65 20 63 61 6c 6c 65 72 2e 20 49 66 20 74  the caller. If t
0a20: 68 65 20 74 68 69 72 64 20 61 72 67 75 6d 65 6e  he third argumen
0a30: 74 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 74  t is non-zero, t
0a40: 68 65 6e 0a 23 20 69 6e 66 6f 20 69 73 20 72 65  hen.# info is re
0a50: 74 75 72 6e 65 64 20 66 6f 72 20 74 68 65 20 70  turned for the p
0a60: 61 67 65 20 74 68 61 74 20 6c 69 65 73 20 24 75  age that lies $u
0a70: 70 20 65 6e 74 72 69 65 73 20 75 70 77 61 72 64  p entries upward
0a80: 73 20 69 6e 20 74 68 65 0a 23 20 74 72 65 65 2d  s in the.# tree-
0a90: 73 74 72 75 63 74 75 72 65 2e 20 28 69 2e 65 2e  structure. (i.e.
0aa0: 20 24 75 70 3d 3d 31 20 72 65 74 75 72 6e 73 20   $up==1 returns 
0ab0: 74 68 65 20 70 61 72 65 6e 74 20 70 61 67 65 2c  the parent page,
0ac0: 20 24 75 70 3d 3d 32 20 74 68 65 20 0a 23 20 67   $up==2 the .# g
0ad0: 72 61 6e 64 70 61 72 65 6e 74 20 65 74 63 2e 29  randparent etc.)
0ae0: 0a 23 0a 23 20 54 68 65 20 66 6f 6c 6c 6f 77 69  .#.# The followi
0af0: 6e 67 20 65 6e 74 72 69 65 73 20 69 6e 20 74 68  ng entries in th
0b00: 61 74 20 61 72 72 61 79 20 61 72 65 20 66 69 6c  at array are fil
0b10: 6c 65 64 20 69 6e 20 77 69 74 68 20 69 6e 66 6f  led in with info
0b20: 72 6d 61 74 69 6f 6e 20 72 65 74 72 69 65 76 65  rmation retrieve
0b30: 64 0a 23 20 75 73 69 6e 67 20 5b 62 74 72 65 65  d.# using [btree
0b40: 5f 63 75 72 73 6f 72 5f 69 6e 66 6f 5d 3a 0a 23  _cursor_info]:.#
0b50: 0a 23 20 20 20 24 61 72 72 61 79 76 61 72 28 70  .#   $arrayvar(p
0b60: 61 67 65 5f 6e 6f 29 20 20 20 20 20 20 20 20 20  age_no)         
0b70: 20 20 20 20 3d 20 20 54 68 65 20 70 61 67 65 20      =  The page 
0b80: 6e 75 6d 62 65 72 0a 23 20 20 20 24 61 72 72 61  number.#   $arra
0b90: 79 76 61 72 28 65 6e 74 72 79 5f 6e 6f 29 20 20  yvar(entry_no)  
0ba0: 20 20 20 20 20 20 20 20 20 20 3d 20 20 54 68 65            =  The
0bb0: 20 65 6e 74 72 79 20 6e 75 6d 62 65 72 0a 23 20   entry number.# 
0bc0: 20 20 24 61 72 72 61 79 76 61 72 28 70 61 67 65    $arrayvar(page
0bd0: 5f 65 6e 74 72 69 65 73 29 20 20 20 20 20 20 20  _entries)       
0be0: 20 3d 20 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72   =  Total number
0bf0: 20 6f 66 20 65 6e 74 72 69 65 73 20 6f 6e 20 74   of entries on t
0c00: 68 69 73 20 70 61 67 65 0a 23 20 20 20 24 61 72  his page.#   $ar
0c10: 72 61 79 76 61 72 28 63 65 6c 6c 5f 73 69 7a 65  rayvar(cell_size
0c20: 29 20 20 20 20 20 20 20 20 20 20 20 3d 20 20 43  )           =  C
0c30: 65 6c 6c 20 73 69 7a 65 20 28 6c 6f 63 61 6c 20  ell size (local 
0c40: 70 61 79 6c 6f 61 64 20 2b 20 68 65 61 64 65 72  payload + header
0c50: 29 0a 23 20 20 20 24 61 72 72 61 79 76 61 72 28  ).#   $arrayvar(
0c60: 70 61 67 65 5f 66 72 65 65 62 79 74 65 73 29 20  page_freebytes) 
0c70: 20 20 20 20 20 3d 20 20 4e 75 6d 62 65 72 20 6f       =  Number o
0c80: 66 20 66 72 65 65 20 62 79 74 65 73 20 6f 6e 20  f free bytes on 
0c90: 74 68 69 73 20 70 61 67 65 0a 23 20 20 20 24 61  this page.#   $a
0ca0: 72 72 61 79 76 61 72 28 70 61 67 65 5f 66 72 65  rrayvar(page_fre
0cb0: 65 62 6c 6f 63 6b 73 29 20 20 20 20 20 3d 20 20  eblocks)     =  
0cc0: 4e 75 6d 62 65 72 20 6f 66 20 66 72 65 65 20 62  Number of free b
0cd0: 6c 6f 63 6b 73 20 6f 6e 20 74 68 65 20 70 61 67  locks on the pag
0ce0: 65 0a 23 20 20 20 24 61 72 72 61 79 76 61 72 28  e.#   $arrayvar(
0cf0: 70 61 79 6c 6f 61 64 5f 62 79 74 65 73 29 20 20  payload_bytes)  
0d00: 20 20 20 20 20 3d 20 20 54 6f 74 61 6c 20 70 61       =  Total pa
0d10: 79 6c 6f 61 64 20 73 69 7a 65 20 28 6c 6f 63 61  yload size (loca
0d20: 6c 20 2b 20 6f 76 65 72 66 6c 6f 77 29 0a 23 20  l + overflow).# 
0d30: 20 20 24 61 72 72 61 79 76 61 72 28 68 65 61 64    $arrayvar(head
0d40: 65 72 5f 62 79 74 65 73 29 20 20 20 20 20 20 20  er_bytes)       
0d50: 20 3d 20 20 48 65 61 64 65 72 20 73 69 7a 65 20   =  Header size 
0d60: 69 6e 20 62 79 74 65 73 0a 23 20 20 20 24 61 72  in bytes.#   $ar
0d70: 72 61 79 76 61 72 28 6c 6f 63 61 6c 5f 70 61 79  rayvar(local_pay
0d80: 6c 6f 61 64 5f 62 79 74 65 73 29 20 3d 20 20 4c  load_bytes) =  L
0d90: 6f 63 61 6c 20 70 61 79 6c 6f 61 64 20 73 69 7a  ocal payload siz
0da0: 65 0a 23 20 20 20 24 61 72 72 61 79 76 61 72 28  e.#   $arrayvar(
0db0: 70 61 72 65 6e 74 29 20 20 20 20 20 20 20 20 20  parent)         
0dc0: 20 20 20 20 20 3d 20 20 50 61 72 65 6e 74 20 70       =  Parent p
0dd0: 61 67 65 20 6e 75 6d 62 65 72 0a 23 20 0a 70 72  age number.# .pr
0de0: 6f 63 20 63 75 72 73 6f 72 5f 69 6e 66 6f 20 7b  oc cursor_info {
0df0: 61 72 72 61 79 76 61 72 20 63 73 72 20 7b 75 70  arrayvar csr {up
0e00: 20 30 7d 7d 20 7b 0a 20 20 75 70 76 61 72 20 24   0}} {.  upvar $
0e10: 61 72 72 61 79 76 61 72 20 61 0a 20 20 66 6f 72  arrayvar a.  for
0e20: 65 61 63 68 20 5b 6c 69 73 74 20 61 28 70 61 67  each [list a(pag
0e30: 65 5f 6e 6f 29 20 5c 0a 20 20 20 20 20 20 20 20  e_no) \.        
0e40: 20 20 20 20 20 20 20 20 61 28 65 6e 74 72 79 5f          a(entry_
0e50: 6e 6f 29 20 5c 0a 20 20 20 20 20 20 20 20 20 20  no) \.          
0e60: 20 20 20 20 20 20 61 28 70 61 67 65 5f 65 6e 74        a(page_ent
0e70: 72 69 65 73 29 20 5c 0a 20 20 20 20 20 20 20 20  ries) \.        
0e80: 20 20 20 20 20 20 20 20 61 28 63 65 6c 6c 5f 73          a(cell_s
0e90: 69 7a 65 29 20 5c 0a 20 20 20 20 20 20 20 20 20  ize) \.         
0ea0: 20 20 20 20 20 20 20 61 28 70 61 67 65 5f 66 72         a(page_fr
0eb0: 65 65 62 79 74 65 73 29 20 5c 0a 20 20 20 20 20  eebytes) \.     
0ec0: 20 20 20 20 20 20 20 20 20 20 20 61 28 70 61 67             a(pag
0ed0: 65 5f 66 72 65 65 62 6c 6f 63 6b 73 29 20 5c 0a  e_freeblocks) \.
0ee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ef0: 61 28 70 61 79 6c 6f 61 64 5f 62 79 74 65 73 29  a(payload_bytes)
0f00: 20 5c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20   \.             
0f10: 20 20 20 61 28 68 65 61 64 65 72 5f 62 79 74 65     a(header_byte
0f20: 73 29 20 5c 0a 20 20 20 20 20 20 20 20 20 20 20  s) \.           
0f30: 20 20 20 20 20 61 28 6c 6f 63 61 6c 5f 70 61 79       a(local_pay
0f40: 6c 6f 61 64 5f 62 79 74 65 73 29 20 5c 0a 20 20  load_bytes) \.  
0f50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61 28                a(
0f60: 70 61 72 65 6e 74 29 20 5d 20 5b 62 74 72 65 65  parent) ] [btree
0f70: 5f 63 75 72 73 6f 72 5f 69 6e 66 6f 20 24 63 73  _cursor_info $cs
0f80: 72 20 24 75 70 5d 20 7b 7d 0a 7d 0a 0a 23 20 44  r $up] {}.}..# D
0f90: 65 74 65 72 6d 69 6e 65 20 74 68 65 20 70 61 67  etermine the pag
0fa0: 65 2d 73 69 7a 65 20 6f 66 20 74 68 65 20 64 61  e-size of the da
0fb0: 74 61 62 61 73 65 2e 20 54 68 69 73 20 67 6c 6f  tabase. This glo
0fc0: 62 61 6c 20 76 61 72 69 61 62 6c 65 20 69 73 20  bal variable is 
0fd0: 75 73 65 64 0a 23 20 74 68 72 6f 75 67 68 6f 75  used.# throughou
0fe0: 74 20 74 68 65 20 73 63 72 69 70 74 2e 0a 23 0a  t the script..#.
0ff0: 73 65 74 20 70 61 67 65 53 69 7a 65 20 5b 64 62  set pageSize [db
1000: 20 65 76 61 6c 20 7b 50 52 41 47 4d 41 20 70 61   eval {PRAGMA pa
1010: 67 65 5f 73 69 7a 65 7d 5d 0a 0a 23 20 41 6e 61  ge_size}]..# Ana
1020: 6c 79 7a 65 20 65 76 65 72 79 20 74 61 62 6c 65  lyze every table
1030: 20 69 6e 20 74 68 65 20 64 61 74 61 62 61 73 65   in the database
1040: 2c 20 6f 6e 65 20 61 74 20 61 20 74 69 6d 65 2e  , one at a time.
1050: 0a 23 0a 23 20 54 68 65 20 66 6f 6c 6c 6f 77 69  .#.# The followi
1060: 6e 67 20 71 75 65 72 79 20 72 65 74 75 72 6e 73  ng query returns
1070: 20 74 68 65 20 6e 61 6d 65 20 61 6e 64 20 72 6f   the name and ro
1080: 6f 74 2d 70 61 67 65 20 6f 66 20 65 61 63 68 20  ot-page of each 
1090: 74 61 62 6c 65 20 69 6e 20 74 68 65 0a 23 20 64  table in the.# d
10a0: 61 74 61 62 61 73 65 2c 20 69 6e 63 6c 75 64 69  atabase, includi
10b0: 6e 67 20 74 68 65 20 73 71 6c 69 74 65 5f 6d 61  ng the sqlite_ma
10c0: 73 74 65 72 20 74 61 62 6c 65 2e 0a 23 0a 73 65  ster table..#.se
10d0: 74 20 73 71 6c 20 7b 0a 20 20 53 45 4c 45 43 54  t sql {.  SELECT
10e0: 20 6e 61 6d 65 2c 20 72 6f 6f 74 70 61 67 65 20   name, rootpage 
10f0: 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74  FROM sqlite_mast
1100: 65 72 0a 20 20 20 57 48 45 52 45 20 74 79 70 65  er.   WHERE type
1110: 3d 27 74 61 62 6c 65 27 20 41 4e 44 20 72 6f 6f  ='table' AND roo
1120: 74 70 61 67 65 3e 30 0a 20 20 55 4e 49 4f 4e 20  tpage>0.  UNION 
1130: 41 4c 4c 0a 20 20 53 45 4c 45 43 54 20 27 73 71  ALL.  SELECT 'sq
1140: 6c 69 74 65 5f 6d 61 73 74 65 72 27 2c 20 31 0a  lite_master', 1.
1150: 20 20 4f 52 44 45 52 20 42 59 20 31 0a 7d 0a 73    ORDER BY 1.}.s
1160: 65 74 20 77 69 64 65 5a 65 72 6f 20 5b 65 78 70  et wideZero [exp
1170: 72 20 7b 31 30 30 30 30 30 30 30 30 30 30 20 2d  r {10000000000 -
1180: 20 31 30 30 30 30 30 30 30 30 30 30 7d 5d 0a 66   10000000000}].f
1190: 6f 72 65 61 63 68 20 7b 6e 61 6d 65 20 72 6f 6f  oreach {name roo
11a0: 74 70 61 67 65 7d 20 5b 64 62 20 65 76 61 6c 20  tpage} [db eval 
11b0: 24 73 71 6c 5d 20 7b 0a 20 20 70 75 74 73 20 73  $sql] {.  puts s
11c0: 74 64 65 72 72 20 22 41 6e 61 6c 79 7a 69 6e 67  tderr "Analyzing
11d0: 20 74 61 62 6c 65 20 24 6e 61 6d 65 2e 2e 2e 22   table $name..."
11e0: 0a 0a 20 20 23 20 43 6f 64 65 20 62 65 6c 6f 77  ..  # Code below
11f0: 20 74 72 61 76 65 72 73 65 73 20 74 68 65 20 74   traverses the t
1200: 61 62 6c 65 20 62 65 69 6e 67 20 61 6e 61 6c 79  able being analy
1210: 7a 65 64 20 28 74 61 62 6c 65 20 6e 61 6d 65 20  zed (table name 
1220: 24 6e 61 6d 65 29 2c 20 75 73 69 6e 67 20 74 68  $name), using th
1230: 65 0a 20 20 23 20 62 74 72 65 65 20 63 75 72 73  e.  # btree curs
1240: 6f 72 20 24 63 75 72 73 6f 72 2e 20 53 74 61 74  or $cursor. Stat
1250: 69 73 74 69 63 73 20 72 65 6c 61 74 65 64 20 74  istics related t
1260: 6f 20 74 61 62 6c 65 20 24 6e 61 6d 65 20 61 72  o table $name ar
1270: 65 20 61 63 63 75 6d 75 6c 61 74 65 64 20 69 6e  e accumulated in
1280: 0a 20 20 23 20 74 68 65 20 66 6f 6c 6c 6f 77 69  .  # the followi
1290: 6e 67 20 76 61 72 69 61 62 6c 65 73 3a 0a 20 20  ng variables:.  
12a0: 23 0a 20 20 73 65 74 20 74 6f 74 61 6c 5f 70 61  #.  set total_pa
12b0: 79 6c 6f 61 64 20 24 77 69 64 65 5a 65 72 6f 20  yload $wideZero 
12c0: 20 20 20 20 20 20 20 3b 23 20 50 61 79 6c 6f 61         ;# Payloa
12d0: 64 20 73 70 61 63 65 20 75 73 65 64 20 62 79 20  d space used by 
12e0: 61 6c 6c 20 65 6e 74 72 69 65 73 0a 20 20 73 65  all entries.  se
12f0: 74 20 74 6f 74 61 6c 5f 6f 76 66 6c 20 24 77 69  t total_ovfl $wi
1300: 64 65 5a 65 72 6f 20 20 20 20 20 20 20 20 20 20  deZero          
1310: 20 3b 23 20 50 61 79 6c 6f 61 64 20 73 70 61 63   ;# Payload spac
1320: 65 20 6f 6e 20 6f 76 65 72 66 6c 6f 77 20 70 61  e on overflow pa
1330: 67 65 73 0a 20 20 73 65 74 20 75 6e 75 73 65 64  ges.  set unused
1340: 5f 69 6e 74 20 24 77 69 64 65 5a 65 72 6f 20 20  _int $wideZero  
1350: 20 20 20 20 20 20 20 20 20 3b 23 20 55 6e 75 73           ;# Unus
1360: 65 64 20 73 70 61 63 65 20 6f 6e 20 69 6e 74 65  ed space on inte
1370: 72 69 6f 72 20 6e 6f 64 65 73 0a 20 20 73 65 74  rior nodes.  set
1380: 20 75 6e 75 73 65 64 5f 6c 65 61 66 20 24 77 69   unused_leaf $wi
1390: 64 65 5a 65 72 6f 20 20 20 20 20 20 20 20 20 20  deZero          
13a0: 3b 23 20 55 6e 75 73 65 64 20 73 70 61 63 65 20  ;# Unused space 
13b0: 6f 6e 20 6c 65 61 66 20 6e 6f 64 65 73 0a 20 20  on leaf nodes.  
13c0: 73 65 74 20 75 6e 75 73 65 64 5f 6f 76 66 6c 20  set unused_ovfl 
13d0: 24 77 69 64 65 5a 65 72 6f 20 20 20 20 20 20 20  $wideZero       
13e0: 20 20 20 3b 23 20 55 6e 75 73 65 64 20 73 70 61     ;# Unused spa
13f0: 63 65 20 6f 6e 20 6f 76 65 72 66 6c 6f 77 20 70  ce on overflow p
1400: 61 67 65 73 0a 20 20 73 65 74 20 63 6e 74 5f 6f  ages.  set cnt_o
1410: 76 66 6c 20 24 77 69 64 65 5a 65 72 6f 20 20 20  vfl $wideZero   
1420: 20 20 20 20 20 20 20 20 20 20 3b 23 20 4e 75 6d            ;# Num
1430: 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20 74  ber of entries t
1440: 68 61 74 20 75 73 65 20 6f 76 65 72 66 6c 6f 77  hat use overflow
1450: 73 0a 20 20 73 65 74 20 63 6e 74 5f 6c 65 61 66  s.  set cnt_leaf
1460: 5f 65 6e 74 72 79 20 24 77 69 64 65 5a 65 72 6f  _entry $wideZero
1470: 20 20 20 20 20 20 20 3b 23 20 4e 75 6d 62 65 72         ;# Number
1480: 20 6f 66 20 6c 65 61 66 20 65 6e 74 72 69 65 73   of leaf entries
1490: 0a 20 20 73 65 74 20 63 6e 74 5f 69 6e 74 5f 65  .  set cnt_int_e
14a0: 6e 74 72 79 20 24 77 69 64 65 5a 65 72 6f 20 20  ntry $wideZero  
14b0: 20 20 20 20 20 20 3b 23 20 4e 75 6d 62 65 72 20        ;# Number 
14c0: 6f 66 20 69 6e 74 65 72 6f 72 20 65 6e 74 72 69  of interor entri
14d0: 65 73 0a 20 20 73 65 74 20 6d 78 5f 70 61 79 6c  es.  set mx_payl
14e0: 6f 61 64 20 24 77 69 64 65 5a 65 72 6f 20 20 20  oad $wideZero   
14f0: 20 20 20 20 20 20 20 20 3b 23 20 4d 61 78 69 6d          ;# Maxim
1500: 75 6d 20 70 61 79 6c 6f 61 64 20 73 69 7a 65 0a  um payload size.
1510: 20 20 73 65 74 20 6f 76 66 6c 5f 70 61 67 65 73    set ovfl_pages
1520: 20 24 77 69 64 65 5a 65 72 6f 20 20 20 20 20 20   $wideZero      
1530: 20 20 20 20 20 3b 23 20 4e 75 6d 62 65 72 20 6f       ;# Number o
1540: 66 20 6f 76 65 72 66 6c 6f 77 20 70 61 67 65 73  f overflow pages
1550: 20 75 73 65 64 0a 20 20 73 65 74 20 6c 65 61 66   used.  set leaf
1560: 5f 70 61 67 65 73 20 24 77 69 64 65 5a 65 72 6f  _pages $wideZero
1570: 20 20 20 20 20 20 20 20 20 20 20 3b 23 20 4e 75             ;# Nu
1580: 6d 62 65 72 20 6f 66 20 6c 65 61 66 20 70 61 67  mber of leaf pag
1590: 65 73 0a 20 20 73 65 74 20 69 6e 74 5f 70 61 67  es.  set int_pag
15a0: 65 73 20 24 77 69 64 65 5a 65 72 6f 20 20 20 20  es $wideZero    
15b0: 20 20 20 20 20 20 20 20 3b 23 20 4e 75 6d 62 65          ;# Numbe
15c0: 72 20 6f 66 20 69 6e 74 65 72 69 6f 72 20 70 61  r of interior pa
15d0: 67 65 73 0a 0a 20 20 23 20 41 73 20 74 68 65 20  ges..  # As the 
15e0: 62 74 72 65 65 20 69 73 20 74 72 61 76 65 72 73  btree is travers
15f0: 65 64 2c 20 74 68 65 20 61 72 72 61 79 20 76 61  ed, the array va
1600: 72 69 61 62 6c 65 20 24 73 65 65 6e 28 24 70 67  riable $seen($pg
1610: 6e 6f 29 20 69 73 20 73 65 74 20 74 6f 20 31 0a  no) is set to 1.
1620: 20 20 23 20 74 68 65 20 66 69 72 73 74 20 74 69    # the first ti
1630: 6d 65 20 70 61 67 65 20 24 70 67 6e 6f 20 69 73  me page $pgno is
1640: 20 65 6e 63 6f 75 6e 74 65 72 65 64 2e 0a 20 20   encountered..  
1650: 23 0a 20 20 63 61 74 63 68 20 7b 75 6e 73 65 74  #.  catch {unset
1660: 20 73 65 65 6e 7d 0a 0a 20 20 23 20 54 68 65 20   seen}..  # The 
1670: 66 6f 6c 6c 6f 77 69 6e 67 20 6c 6f 6f 70 20 72  following loop r
1680: 75 6e 73 20 6f 6e 63 65 20 66 6f 72 20 65 61 63  uns once for eac
1690: 68 20 65 6e 74 72 79 20 69 6e 20 74 61 62 6c 65  h entry in table
16a0: 20 24 6e 61 6d 65 2e 20 54 68 65 20 74 61 62 6c   $name. The tabl
16b0: 65 0a 20 20 23 20 69 73 20 74 72 61 76 65 72 73  e.  # is travers
16c0: 65 64 20 75 73 69 6e 67 20 74 68 65 20 62 74 72  ed using the btr
16d0: 65 65 20 63 75 72 73 6f 72 20 73 74 6f 72 65 64  ee cursor stored
16e0: 20 69 6e 20 76 61 72 69 61 62 6c 65 20 24 63 73   in variable $cs
16f0: 72 0a 20 20 23 0a 20 20 73 65 74 20 63 73 72 20  r.  #.  set csr 
1700: 5b 62 74 72 65 65 5f 63 75 72 73 6f 72 20 24 44  [btree_cursor $D
1710: 42 20 24 72 6f 6f 74 70 61 67 65 20 30 5d 0a 20  B $rootpage 0]. 
1720: 20 66 6f 72 20 7b 62 74 72 65 65 5f 66 69 72 73   for {btree_firs
1730: 74 20 24 63 73 72 7d 20 7b 21 5b 62 74 72 65 65  t $csr} {![btree
1740: 5f 65 6f 66 20 24 63 73 72 5d 7d 20 7b 62 74 72  _eof $csr]} {btr
1750: 65 65 5f 6e 65 78 74 20 24 63 73 72 7d 20 7b 0a  ee_next $csr} {.
1760: 20 20 20 20 69 6e 63 72 20 63 6e 74 5f 6c 65 61      incr cnt_lea
1770: 66 5f 65 6e 74 72 79 0a 0a 20 20 20 20 23 20 52  f_entry..    # R
1780: 65 74 72 69 65 76 65 20 69 6e 66 6f 72 6d 61 74  etrieve informat
1790: 69 6f 6e 20 61 62 6f 75 74 20 74 68 65 20 65 6e  ion about the en
17a0: 74 72 79 20 74 68 65 20 62 74 72 65 65 2d 63 75  try the btree-cu
17b0: 72 73 6f 72 20 70 6f 69 6e 74 73 20 74 6f 20 69  rsor points to i
17c0: 6e 74 6f 0a 20 20 20 20 23 20 74 68 65 20 61 72  nto.    # the ar
17d0: 72 61 79 20 76 61 72 69 61 62 6c 65 20 24 63 69  ray variable $ci
17e0: 20 28 63 75 72 73 6f 72 20 69 6e 66 6f 29 2e 0a   (cursor info)..
17f0: 20 20 20 20 23 0a 20 20 20 20 63 75 72 73 6f 72      #.    cursor
1800: 5f 69 6e 66 6f 20 63 69 20 24 63 73 72 0a 0a 20  _info ci $csr.. 
1810: 20 20 20 23 20 43 68 65 63 6b 20 69 66 20 74 68     # Check if th
1820: 65 20 70 61 79 6c 6f 61 64 20 6f 66 20 74 68 69  e payload of thi
1830: 73 20 65 6e 74 72 79 20 69 73 20 67 72 65 61 74  s entry is great
1840: 65 72 20 74 68 61 6e 20 74 68 65 20 63 75 72 72  er than the curr
1850: 65 6e 74 20 0a 20 20 20 20 23 20 24 6d 78 5f 70  ent .    # $mx_p
1860: 61 79 6c 6f 61 64 20 73 74 61 74 69 73 74 69 63  ayload statistic
1870: 20 66 6f 72 20 74 68 65 20 74 61 62 6c 65 2e 20   for the table. 
1880: 41 6c 73 6f 20 69 6e 63 72 65 61 73 65 20 74 68  Also increase th
1890: 65 20 24 74 6f 74 61 6c 5f 70 61 79 6c 6f 61 64  e $total_payload
18a0: 0a 20 20 20 20 23 20 73 74 61 74 69 73 74 69 63  .    # statistic
18b0: 2e 0a 20 20 20 20 23 0a 20 20 20 20 69 66 20 7b  ..    #.    if {
18c0: 24 63 69 28 70 61 79 6c 6f 61 64 5f 62 79 74 65  $ci(payload_byte
18d0: 73 29 3e 24 6d 78 5f 70 61 79 6c 6f 61 64 7d 20  s)>$mx_payload} 
18e0: 7b 73 65 74 20 6d 78 5f 70 61 79 6c 6f 61 64 20  {set mx_payload 
18f0: 24 63 69 28 70 61 79 6c 6f 61 64 5f 62 79 74 65  $ci(payload_byte
1900: 73 29 7d 0a 20 20 20 20 69 6e 63 72 20 74 6f 74  s)}.    incr tot
1910: 61 6c 5f 70 61 79 6c 6f 61 64 20 24 63 69 28 70  al_payload $ci(p
1920: 61 79 6c 6f 61 64 5f 62 79 74 65 73 29 0a 0a 20  ayload_bytes).. 
1930: 20 20 20 23 20 49 66 20 74 68 69 73 20 65 6e 74     # If this ent
1940: 72 79 20 75 73 65 73 20 6f 76 65 72 66 6c 6f 77  ry uses overflow
1950: 20 70 61 67 65 73 2c 20 74 68 65 6e 20 75 70 64   pages, then upd
1960: 61 74 65 20 74 68 65 20 24 63 6e 74 5f 6f 76 66  ate the $cnt_ovf
1970: 6c 2c 20 0a 20 20 20 20 23 20 24 74 6f 74 61 6c  l, .    # $total
1980: 5f 6f 76 66 6c 2c 20 24 6f 76 66 6c 5f 70 61 67  _ovfl, $ovfl_pag
1990: 65 73 20 61 6e 64 20 24 75 6e 75 73 65 64 5f 6f  es and $unused_o
19a0: 76 66 6c 20 73 74 61 74 69 73 74 69 63 73 2e 0a  vfl statistics..
19b0: 20 20 20 20 23 0a 20 20 20 20 73 65 74 20 6f 76      #.    set ov
19c0: 66 6c 20 5b 65 78 70 72 20 7b 24 63 69 28 70 61  fl [expr {$ci(pa
19d0: 79 6c 6f 61 64 5f 62 79 74 65 73 29 2d 24 63 69  yload_bytes)-$ci
19e0: 28 6c 6f 63 61 6c 5f 70 61 79 6c 6f 61 64 5f 62  (local_payload_b
19f0: 79 74 65 73 29 7d 5d 0a 20 20 20 20 69 66 20 7b  ytes)}].    if {
1a00: 24 6f 76 66 6c 7d 20 7b 0a 20 20 20 20 20 20 69  $ovfl} {.      i
1a10: 6e 63 72 20 63 6e 74 5f 6f 76 66 6c 0a 20 20 20  ncr cnt_ovfl.   
1a20: 20 20 20 69 6e 63 72 20 74 6f 74 61 6c 5f 6f 76     incr total_ov
1a30: 66 6c 20 24 6f 76 66 6c 0a 20 20 20 20 20 20 73  fl $ovfl.      s
1a40: 65 74 20 6e 20 5b 65 78 70 72 20 7b 69 6e 74 28  et n [expr {int(
1a50: 63 65 69 6c 28 24 6f 76 66 6c 2f 28 24 70 61 67  ceil($ovfl/($pag
1a60: 65 53 69 7a 65 2d 34 2e 30 29 29 29 7d 5d 0a 20  eSize-4.0)))}]. 
1a70: 20 20 20 20 20 69 6e 63 72 20 6f 76 66 6c 5f 70       incr ovfl_p
1a80: 61 67 65 73 20 24 6e 0a 20 20 20 20 20 20 69 6e  ages $n.      in
1a90: 63 72 20 75 6e 75 73 65 64 5f 6f 76 66 6c 20 5b  cr unused_ovfl [
1aa0: 65 78 70 72 20 7b 24 6e 2a 28 24 70 61 67 65 53  expr {$n*($pageS
1ab0: 69 7a 65 2d 34 29 20 2d 20 24 6f 76 66 6c 7d 5d  ize-4) - $ovfl}]
1ac0: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 23 20 49 66  .    }..    # If
1ad0: 20 74 68 69 73 20 69 73 20 74 68 65 20 66 69 72   this is the fir
1ae0: 73 74 20 74 61 62 6c 65 20 65 6e 74 72 79 20 61  st table entry a
1af0: 6e 61 6c 79 7a 65 64 20 66 6f 72 20 74 68 65 20  nalyzed for the 
1b00: 70 61 67 65 2c 20 74 68 65 6e 20 75 70 64 61 74  page, then updat
1b10: 65 0a 20 20 20 20 23 20 74 68 65 20 70 61 67 65  e.    # the page
1b20: 2d 72 65 6c 61 74 65 64 20 73 74 61 74 69 73 74  -related statist
1b30: 69 63 73 20 24 6c 65 61 66 5f 70 61 67 65 73 20  ics $leaf_pages 
1b40: 61 6e 64 20 24 75 6e 75 73 65 64 5f 6c 65 61 66  and $unused_leaf
1b50: 2e 20 41 6c 73 6f 2c 20 69 66 0a 20 20 20 20 23  . Also, if.    #
1b60: 20 74 68 69 73 20 70 61 67 65 20 68 61 73 20 61   this page has a
1b70: 20 70 61 72 65 6e 74 20 70 61 67 65 20 74 68 61   parent page tha
1b80: 74 20 68 61 73 20 6e 6f 74 20 62 65 65 6e 20 61  t has not been a
1b90: 6e 61 6c 79 7a 65 64 2c 20 72 65 74 72 69 65 76  nalyzed, retriev
1ba0: 65 0a 20 20 20 20 23 20 69 6e 66 6f 20 66 6f 72  e.    # info for
1bb0: 20 74 68 65 20 70 61 72 65 6e 74 20 61 6e 64 20   the parent and 
1bc0: 75 70 64 61 74 65 20 73 74 61 74 69 73 74 69 63  update statistic
1bd0: 73 20 66 6f 72 20 69 74 20 74 6f 6f 2e 0a 20 20  s for it too..  
1be0: 20 20 23 0a 20 20 20 20 69 66 20 7b 21 5b 69 6e    #.    if {![in
1bf0: 66 6f 20 65 78 69 73 74 73 20 73 65 65 6e 28 24  fo exists seen($
1c00: 63 69 28 70 61 67 65 5f 6e 6f 29 29 5d 7d 20 7b  ci(page_no))]} {
1c10: 0a 20 20 20 20 20 20 73 65 74 20 73 65 65 6e 28  .      set seen(
1c20: 24 63 69 28 70 61 67 65 5f 6e 6f 29 29 20 31 0a  $ci(page_no)) 1.
1c30: 20 20 20 20 20 20 69 6e 63 72 20 6c 65 61 66 5f        incr leaf_
1c40: 70 61 67 65 73 0a 20 20 20 20 20 20 69 6e 63 72  pages.      incr
1c50: 20 75 6e 75 73 65 64 5f 6c 65 61 66 20 24 63 69   unused_leaf $ci
1c60: 28 70 61 67 65 5f 66 72 65 65 62 79 74 65 73 29  (page_freebytes)
1c70: 0a 0a 20 20 20 20 20 20 23 20 4e 6f 77 20 63 68  ..      # Now ch
1c80: 65 63 6b 20 69 66 20 74 68 65 20 70 61 67 65 20  eck if the page 
1c90: 68 61 73 20 61 20 70 61 72 65 6e 74 20 74 68 61  has a parent tha
1ca0: 74 20 68 61 73 20 6e 6f 74 20 62 65 65 6e 20 61  t has not been a
1cb0: 6e 61 6c 79 7a 65 64 2e 20 49 66 0a 20 20 20 20  nalyzed. If.    
1cc0: 20 20 23 20 73 6f 2c 20 75 70 64 61 74 65 20 74    # so, update t
1cd0: 68 65 20 24 69 6e 74 5f 70 61 67 65 73 2c 20 24  he $int_pages, $
1ce0: 63 6e 74 5f 69 6e 74 5f 65 6e 74 72 79 20 61 6e  cnt_int_entry an
1cf0: 64 20 24 75 6e 75 73 65 64 5f 69 6e 74 20 73 74  d $unused_int st
1d00: 61 74 69 73 74 69 63 73 0a 20 20 20 20 20 20 23  atistics.      #
1d10: 20 61 63 63 6f 72 64 69 6e 67 6c 79 2e 20 54 68   accordingly. Th
1d20: 65 6e 20 63 68 65 63 6b 20 69 66 20 74 68 65 20  en check if the 
1d30: 70 61 72 65 6e 74 20 70 61 67 65 20 68 61 73 20  parent page has 
1d40: 61 20 70 61 72 65 6e 74 20 74 68 61 74 20 68 61  a parent that ha
1d50: 73 0a 20 20 20 20 20 20 23 20 6e 6f 74 20 79 65  s.      # not ye
1d60: 74 20 62 65 65 6e 20 61 6e 61 6c 79 7a 65 64 20  t been analyzed 
1d70: 65 74 63 2e 0a 20 20 20 20 20 20 23 0a 20 20 20  etc..      #.   
1d80: 20 20 20 23 20 73 65 74 20 70 61 72 65 6e 74 20     # set parent 
1d90: 24 63 69 28 70 61 72 65 6e 74 5f 70 61 67 65 5f  $ci(parent_page_
1da0: 6e 6f 29 0a 20 20 20 20 20 20 66 6f 72 20 7b 73  no).      for {s
1db0: 65 74 20 75 70 20 31 7d 20 5c 0a 20 20 20 20 20  et up 1} \.     
1dc0: 20 20 20 20 20 7b 24 63 69 28 70 61 72 65 6e 74       {$ci(parent
1dd0: 29 21 3d 30 20 26 26 20 21 5b 69 6e 66 6f 20 65  )!=0 && ![info e
1de0: 78 69 73 74 73 20 73 65 65 6e 28 24 63 69 28 70  xists seen($ci(p
1df0: 61 72 65 6e 74 29 29 5d 7d 20 7b 69 6e 63 72 20  arent))]} {incr 
1e00: 75 70 7d 20 5c 0a 20 20 20 20 20 20 7b 0a 20 20  up} \.      {.  
1e10: 20 20 20 20 20 20 23 20 4d 61 72 6b 20 74 68 65        # Mark the
1e20: 20 70 61 72 65 6e 74 20 61 73 20 73 65 65 6e 2e   parent as seen.
1e30: 0a 20 20 20 20 20 20 20 20 23 0a 20 20 20 20 20  .        #.     
1e40: 20 20 20 73 65 74 20 73 65 65 6e 28 24 63 69 28     set seen($ci(
1e50: 70 61 72 65 6e 74 29 29 20 31 0a 0a 20 20 20 20  parent)) 1..    
1e60: 20 20 20 20 23 20 52 65 74 72 69 65 76 65 20 69      # Retrieve i
1e70: 6e 66 6f 20 66 6f 72 20 74 68 65 20 70 61 72 65  nfo for the pare
1e80: 6e 74 20 61 6e 64 20 75 70 64 61 74 65 20 73 74  nt and update st
1e90: 61 74 69 73 74 69 63 73 2e 0a 20 20 20 20 20 20  atistics..      
1ea0: 20 20 63 75 72 73 6f 72 5f 69 6e 66 6f 20 63 69    cursor_info ci
1eb0: 20 24 63 73 72 20 24 75 70 0a 20 20 20 20 20 20   $csr $up.      
1ec0: 20 20 69 6e 63 72 20 69 6e 74 5f 70 61 67 65 73    incr int_pages
1ed0: 0a 20 20 20 20 20 20 20 20 69 6e 63 72 20 63 6e  .        incr cn
1ee0: 74 5f 69 6e 74 5f 65 6e 74 72 79 20 24 63 69 28  t_int_entry $ci(
1ef0: 70 61 67 65 5f 65 6e 74 72 69 65 73 29 0a 20 20  page_entries).  
1f00: 20 20 20 20 20 20 69 6e 63 72 20 75 6e 75 73 65        incr unuse
1f10: 64 5f 69 6e 74 20 24 63 69 28 70 61 67 65 5f 66  d_int $ci(page_f
1f20: 72 65 65 62 79 74 65 73 29 0a 20 20 20 20 20 20  reebytes).      
1f30: 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 62 74  }.    }.  }.  bt
1f40: 72 65 65 5f 63 6c 6f 73 65 5f 63 75 72 73 6f 72  ree_close_cursor
1f50: 20 24 63 73 72 0a 0a 20 20 23 20 48 61 6e 64 6c   $csr..  # Handl
1f60: 65 20 74 68 65 20 73 70 65 63 69 61 6c 20 63 61  e the special ca
1f70: 73 65 20 77 68 65 72 65 20 61 20 74 61 62 6c 65  se where a table
1f80: 20 63 6f 6e 74 61 69 6e 73 20 6e 6f 20 64 61 74   contains no dat
1f90: 61 2e 20 49 6e 20 74 68 69 73 20 63 61 73 65 0a  a. In this case.
1fa0: 20 20 23 20 61 6c 6c 20 73 74 61 74 69 73 74 69    # all statisti
1fb0: 63 73 20 61 72 65 20 7a 65 72 6f 2c 20 65 78 63  cs are zero, exc
1fc0: 65 70 74 20 66 6f 72 20 74 68 65 20 6e 75 6d 62  ept for the numb
1fd0: 65 72 20 6f 66 20 6c 65 61 66 20 70 61 67 65 73  er of leaf pages
1fe0: 20 28 31 29 20 61 6e 64 0a 20 20 23 20 74 68 65   (1) and.  # the
1ff0: 20 75 6e 75 73 65 64 20 62 79 74 65 73 20 6f 6e   unused bytes on
2000: 20 6c 65 61 66 20 70 61 67 65 73 20 28 24 70 61   leaf pages ($pa
2010: 67 65 53 69 7a 65 20 2d 20 38 29 2e 0a 20 20 23  geSize - 8)..  #
2020: 0a 20 20 23 20 41 6e 20 65 78 63 65 70 74 69 6f  .  # An exceptio
2030: 6e 20 74 6f 20 74 68 65 20 61 62 6f 76 65 20 69  n to the above i
2040: 73 20 74 68 65 20 73 71 6c 69 74 65 5f 6d 61 73  s the sqlite_mas
2050: 74 65 72 20 74 61 62 6c 65 2e 20 49 66 20 69 74  ter table. If it
2060: 20 69 73 20 65 6d 70 74 79 0a 20 20 23 20 74 68   is empty.  # th
2070: 65 6e 20 61 6c 6c 20 73 74 61 74 69 73 74 69 63  en all statistic
2080: 73 20 61 72 65 20 7a 65 72 6f 20 65 78 63 65 70  s are zero excep
2090: 74 20 66 6f 72 20 74 68 65 20 6e 75 6d 62 65 72  t for the number
20a0: 20 6f 66 20 6c 65 61 66 20 70 61 67 65 73 20 28   of leaf pages (
20b0: 31 29 2c 0a 20 20 23 20 61 6e 64 20 74 68 65 20  1),.  # and the 
20c0: 6e 75 6d 62 65 72 20 6f 66 20 75 6e 75 73 65 64  number of unused
20d0: 20 62 79 74 65 73 20 6f 6e 20 6c 65 61 66 20 70   bytes on leaf p
20e0: 61 67 65 73 20 28 24 70 61 67 65 53 69 7a 65 20  ages ($pageSize 
20f0: 2d 20 31 31 32 29 2e 0a 20 20 23 0a 20 20 69 66  - 112)..  #.  if
2100: 20 7b 5b 6c 6c 65 6e 67 74 68 20 5b 61 72 72 61   {[llength [arra
2110: 79 20 6e 61 6d 65 73 20 73 65 65 6e 5d 5d 3d 3d  y names seen]]==
2120: 30 7d 20 7b 0a 20 20 20 20 73 65 74 20 6c 65 61  0} {.    set lea
2130: 66 5f 70 61 67 65 73 20 31 0a 20 20 20 20 69 66  f_pages 1.    if
2140: 20 7b 24 72 6f 6f 74 70 61 67 65 3d 3d 31 7d 20   {$rootpage==1} 
2150: 7b 0a 20 20 20 20 20 20 73 65 74 20 75 6e 75 73  {.      set unus
2160: 65 64 5f 6c 65 61 66 20 5b 65 78 70 72 20 7b 24  ed_leaf [expr {$
2170: 70 61 67 65 53 69 7a 65 2d 31 31 32 7d 5d 0a 20  pageSize-112}]. 
2180: 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20     } else {.    
2190: 20 20 73 65 74 20 75 6e 75 73 65 64 5f 6c 65 61    set unused_lea
21a0: 66 20 5b 65 78 70 72 20 7b 24 70 61 67 65 53 69  f [expr {$pageSi
21b0: 7a 65 2d 38 7d 5d 0a 20 20 20 20 7d 0a 20 20 7d  ze-8}].    }.  }
21c0: 0a 0a 20 20 23 20 49 6e 73 65 72 74 20 74 68 65  ..  # Insert the
21d0: 20 73 74 61 74 69 73 74 69 63 73 20 66 6f 72 20   statistics for 
21e0: 74 68 65 20 74 61 62 6c 65 20 61 6e 61 6c 79 7a  the table analyz
21f0: 65 64 20 69 6e 74 6f 20 74 68 65 20 69 6e 2d 6d  ed into the in-m
2200: 65 6d 6f 72 79 20 64 61 74 61 62 61 73 65 2e 0a  emory database..
2210: 20 20 23 0a 20 20 73 65 74 20 73 71 6c 20 22 49    #.  set sql "I
2220: 4e 53 45 52 54 20 49 4e 54 4f 20 73 70 61 63 65  NSERT INTO space
2230: 5f 75 73 65 64 20 56 41 4c 55 45 53 28 22 0a 20  _used VALUES(". 
2240: 20 61 70 70 65 6e 64 20 73 71 6c 20 5b 71 75 6f   append sql [quo
2250: 74 65 20 24 6e 61 6d 65 5d 0a 20 20 61 70 70 65  te $name].  appe
2260: 6e 64 20 73 71 6c 20 22 2c 5b 71 75 6f 74 65 20  nd sql ",[quote 
2270: 24 6e 61 6d 65 5d 22 0a 20 20 61 70 70 65 6e 64  $name]".  append
2280: 20 73 71 6c 20 22 2c 30 22 0a 20 20 61 70 70 65   sql ",0".  appe
2290: 6e 64 20 73 71 6c 20 22 2c 5b 65 78 70 72 20 7b  nd sql ",[expr {
22a0: 24 63 6e 74 5f 6c 65 61 66 5f 65 6e 74 72 79 2b  $cnt_leaf_entry+
22b0: 24 63 6e 74 5f 69 6e 74 5f 65 6e 74 72 79 7d 5d  $cnt_int_entry}]
22c0: 22 0a 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22  ".  append sql "
22d0: 2c 24 63 6e 74 5f 6c 65 61 66 5f 65 6e 74 72 79  ,$cnt_leaf_entry
22e0: 22 0a 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22  ".  append sql "
22f0: 2c 24 74 6f 74 61 6c 5f 70 61 79 6c 6f 61 64 22  ,$total_payload"
2300: 0a 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22 2c  .  append sql ",
2310: 24 74 6f 74 61 6c 5f 6f 76 66 6c 22 0a 20 20 61  $total_ovfl".  a
2320: 70 70 65 6e 64 20 73 71 6c 20 22 2c 24 63 6e 74  ppend sql ",$cnt
2330: 5f 6f 76 66 6c 22 0a 20 20 61 70 70 65 6e 64 20  _ovfl".  append 
2340: 73 71 6c 20 22 2c 24 6d 78 5f 70 61 79 6c 6f 61  sql ",$mx_payloa
2350: 64 22 0a 20 20 61 70 70 65 6e 64 20 73 71 6c 20  d".  append sql 
2360: 22 2c 24 69 6e 74 5f 70 61 67 65 73 22 0a 20 20  ",$int_pages".  
2370: 61 70 70 65 6e 64 20 73 71 6c 20 22 2c 24 6c 65  append sql ",$le
2380: 61 66 5f 70 61 67 65 73 22 0a 20 20 61 70 70 65  af_pages".  appe
2390: 6e 64 20 73 71 6c 20 22 2c 24 6f 76 66 6c 5f 70  nd sql ",$ovfl_p
23a0: 61 67 65 73 22 0a 20 20 61 70 70 65 6e 64 20 73  ages".  append s
23b0: 71 6c 20 22 2c 24 75 6e 75 73 65 64 5f 69 6e 74  ql ",$unused_int
23c0: 22 0a 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22  ".  append sql "
23d0: 2c 24 75 6e 75 73 65 64 5f 6c 65 61 66 22 0a 20  ,$unused_leaf". 
23e0: 20 61 70 70 65 6e 64 20 73 71 6c 20 22 2c 24 75   append sql ",$u
23f0: 6e 75 73 65 64 5f 6f 76 66 6c 22 0a 20 20 61 70  nused_ovfl".  ap
2400: 70 65 6e 64 20 73 71 6c 20 29 3b 0a 20 20 6d 65  pend sql );.  me
2410: 6d 20 65 76 61 6c 20 24 73 71 6c 0a 7d 0a 0a 23  m eval $sql.}..#
2420: 20 41 6e 61 6c 79 7a 65 20 65 76 65 72 79 20 69   Analyze every i
2430: 6e 64 65 78 20 69 6e 20 74 68 65 20 64 61 74 61  ndex in the data
2440: 62 61 73 65 2c 20 6f 6e 65 20 61 74 20 61 20 74  base, one at a t
2450: 69 6d 65 2e 0a 23 0a 23 20 54 68 65 20 71 75 65  ime..#.# The que
2460: 72 79 20 62 65 6c 6f 77 20 72 65 74 75 72 6e 73  ry below returns
2470: 20 74 68 65 20 6e 61 6d 65 2c 20 61 73 73 6f 63   the name, assoc
2480: 69 61 74 65 64 20 74 61 62 6c 65 20 61 6e 64 20  iated table and 
2490: 72 6f 6f 74 2d 70 61 67 65 20 6e 75 6d 62 65 72  root-page number
24a0: 20 0a 23 20 66 6f 72 20 65 76 65 72 79 20 69 6e   .# for every in
24b0: 64 65 78 20 69 6e 20 74 68 65 20 64 61 74 61 62  dex in the datab
24c0: 61 73 65 2e 0a 23 0a 73 65 74 20 73 71 6c 20 7b  ase..#.set sql {
24d0: 0a 20 20 53 45 4c 45 43 54 20 6e 61 6d 65 2c 20  .  SELECT name, 
24e0: 74 62 6c 5f 6e 61 6d 65 2c 20 72 6f 6f 74 70 61  tbl_name, rootpa
24f0: 67 65 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d  ge FROM sqlite_m
2500: 61 73 74 65 72 20 57 48 45 52 45 20 74 79 70 65  aster WHERE type
2510: 3d 27 69 6e 64 65 78 27 0a 20 20 4f 52 44 45 52  ='index'.  ORDER
2520: 20 42 59 20 32 2c 20 31 0a 7d 0a 66 6f 72 65 61   BY 2, 1.}.forea
2530: 63 68 20 7b 6e 61 6d 65 20 74 62 6c 5f 6e 61 6d  ch {name tbl_nam
2540: 65 20 72 6f 6f 74 70 61 67 65 7d 20 5b 64 62 20  e rootpage} [db 
2550: 65 76 61 6c 20 24 73 71 6c 5d 20 7b 0a 20 20 70  eval $sql] {.  p
2560: 75 74 73 20 73 74 64 65 72 72 20 22 41 6e 61 6c  uts stderr "Anal
2570: 79 7a 69 6e 67 20 69 6e 64 65 78 20 24 6e 61 6d  yzing index $nam
2580: 65 20 6f 66 20 74 61 62 6c 65 20 24 74 62 6c 5f  e of table $tbl_
2590: 6e 61 6d 65 2e 2e 2e 22 0a 0a 20 20 23 20 43 6f  name..."..  # Co
25a0: 64 65 20 62 65 6c 6f 77 20 74 72 61 76 65 72 73  de below travers
25b0: 65 73 20 74 68 65 20 69 6e 64 65 78 20 62 65 69  es the index bei
25c0: 6e 67 20 61 6e 61 6c 79 7a 65 64 20 28 69 6e 64  ng analyzed (ind
25d0: 65 78 20 6e 61 6d 65 20 24 6e 61 6d 65 29 2c 20  ex name $name), 
25e0: 75 73 69 6e 67 20 74 68 65 0a 20 20 23 20 62 74  using the.  # bt
25f0: 72 65 65 20 63 75 72 73 6f 72 20 24 63 75 72 73  ree cursor $curs
2600: 6f 72 2e 20 53 74 61 74 69 73 74 69 63 73 20 72  or. Statistics r
2610: 65 6c 61 74 65 64 20 74 6f 20 69 6e 64 65 78 20  elated to index 
2620: 24 6e 61 6d 65 20 61 72 65 20 61 63 63 75 6d 75  $name are accumu
2630: 6c 61 74 65 64 20 69 6e 0a 20 20 23 20 74 68 65  lated in.  # the
2640: 20 66 6f 6c 6c 6f 77 69 6e 67 20 76 61 72 69 61   following varia
2650: 62 6c 65 73 3a 0a 20 20 23 0a 20 20 73 65 74 20  bles:.  #.  set 
2660: 74 6f 74 61 6c 5f 70 61 79 6c 6f 61 64 20 24 77  total_payload $w
2670: 69 64 65 5a 65 72 6f 20 20 20 20 20 20 20 20 3b  ideZero        ;
2680: 23 20 50 61 79 6c 6f 61 64 20 73 70 61 63 65 20  # Payload space 
2690: 75 73 65 64 20 62 79 20 61 6c 6c 20 65 6e 74 72  used by all entr
26a0: 69 65 73 0a 20 20 73 65 74 20 74 6f 74 61 6c 5f  ies.  set total_
26b0: 6f 76 66 6c 20 24 77 69 64 65 5a 65 72 6f 20 20  ovfl $wideZero  
26c0: 20 20 20 20 20 20 20 20 20 3b 23 20 50 61 79 6c           ;# Payl
26d0: 6f 61 64 20 73 70 61 63 65 20 6f 6e 20 6f 76 65  oad space on ove
26e0: 72 66 6c 6f 77 20 70 61 67 65 73 0a 20 20 73 65  rflow pages.  se
26f0: 74 20 75 6e 75 73 65 64 5f 6c 65 61 66 20 24 77  t unused_leaf $w
2700: 69 64 65 5a 65 72 6f 20 20 20 20 20 20 20 20 20  ideZero         
2710: 20 3b 23 20 55 6e 75 73 65 64 20 73 70 61 63 65   ;# Unused space
2720: 20 6f 6e 20 6c 65 61 66 20 6e 6f 64 65 73 0a 20   on leaf nodes. 
2730: 20 73 65 74 20 75 6e 75 73 65 64 5f 6f 76 66 6c   set unused_ovfl
2740: 20 24 77 69 64 65 5a 65 72 6f 20 20 20 20 20 20   $wideZero      
2750: 20 20 20 20 3b 23 20 55 6e 75 73 65 64 20 73 70      ;# Unused sp
2760: 61 63 65 20 6f 6e 20 6f 76 65 72 66 6c 6f 77 20  ace on overflow 
2770: 70 61 67 65 73 0a 20 20 73 65 74 20 63 6e 74 5f  pages.  set cnt_
2780: 6f 76 66 6c 20 24 77 69 64 65 5a 65 72 6f 20 20  ovfl $wideZero  
2790: 20 20 20 20 20 20 20 20 20 20 20 3b 23 20 4e 75             ;# Nu
27a0: 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20  mber of entries 
27b0: 74 68 61 74 20 75 73 65 20 6f 76 65 72 66 6c 6f  that use overflo
27c0: 77 73 0a 20 20 73 65 74 20 63 6e 74 5f 6c 65 61  ws.  set cnt_lea
27d0: 66 5f 65 6e 74 72 79 20 24 77 69 64 65 5a 65 72  f_entry $wideZer
27e0: 6f 20 20 20 20 20 20 20 3b 23 20 4e 75 6d 62 65  o       ;# Numbe
27f0: 72 20 6f 66 20 6c 65 61 66 20 65 6e 74 72 69 65  r of leaf entrie
2800: 73 0a 20 20 73 65 74 20 6d 78 5f 70 61 79 6c 6f  s.  set mx_paylo
2810: 61 64 20 24 77 69 64 65 5a 65 72 6f 20 20 20 20  ad $wideZero    
2820: 20 20 20 20 20 20 20 3b 23 20 4d 61 78 69 6d 75         ;# Maximu
2830: 6d 20 70 61 79 6c 6f 61 64 20 73 69 7a 65 0a 20  m payload size. 
2840: 20 73 65 74 20 6f 76 66 6c 5f 70 61 67 65 73 20   set ovfl_pages 
2850: 24 77 69 64 65 5a 65 72 6f 20 20 20 20 20 20 20  $wideZero       
2860: 20 20 20 20 3b 23 20 4e 75 6d 62 65 72 20 6f 66      ;# Number of
2870: 20 6f 76 65 72 66 6c 6f 77 20 70 61 67 65 73 20   overflow pages 
2880: 75 73 65 64 0a 20 20 73 65 74 20 6c 65 61 66 5f  used.  set leaf_
2890: 70 61 67 65 73 20 24 77 69 64 65 5a 65 72 6f 20  pages $wideZero 
28a0: 20 20 20 20 20 20 20 20 20 20 3b 23 20 4e 75 6d            ;# Num
28b0: 62 65 72 20 6f 66 20 6c 65 61 66 20 70 61 67 65  ber of leaf page
28c0: 73 0a 0a 20 20 23 20 41 73 20 74 68 65 20 62 74  s..  # As the bt
28d0: 72 65 65 20 69 73 20 74 72 61 76 65 72 73 65 64  ree is traversed
28e0: 2c 20 74 68 65 20 61 72 72 61 79 20 76 61 72 69  , the array vari
28f0: 61 62 6c 65 20 24 73 65 65 6e 28 24 70 67 6e 6f  able $seen($pgno
2900: 29 20 69 73 20 73 65 74 20 74 6f 20 31 0a 20 20  ) is set to 1.  
2910: 23 20 74 68 65 20 66 69 72 73 74 20 74 69 6d 65  # the first time
2920: 20 70 61 67 65 20 24 70 67 6e 6f 20 69 73 20 65   page $pgno is e
2930: 6e 63 6f 75 6e 74 65 72 65 64 2e 0a 20 20 23 0a  ncountered..  #.
2940: 20 20 63 61 74 63 68 20 7b 75 6e 73 65 74 20 73    catch {unset s
2950: 65 65 6e 7d 0a 0a 20 20 23 20 54 68 65 20 66 6f  een}..  # The fo
2960: 6c 6c 6f 77 69 6e 67 20 6c 6f 6f 70 20 72 75 6e  llowing loop run
2970: 73 20 6f 6e 63 65 20 66 6f 72 20 65 61 63 68 20  s once for each 
2980: 65 6e 74 72 79 20 69 6e 20 69 6e 64 65 78 20 24  entry in index $
2990: 6e 61 6d 65 2e 20 54 68 65 20 69 6e 64 65 78 0a  name. The index.
29a0: 20 20 23 20 69 73 20 74 72 61 76 65 72 73 65 64    # is traversed
29b0: 20 75 73 69 6e 67 20 74 68 65 20 62 74 72 65 65   using the btree
29c0: 20 63 75 72 73 6f 72 20 73 74 6f 72 65 64 20 69   cursor stored i
29d0: 6e 20 76 61 72 69 61 62 6c 65 20 24 63 73 72 0a  n variable $csr.
29e0: 20 20 23 0a 20 20 73 65 74 20 63 73 72 20 5b 62    #.  set csr [b
29f0: 74 72 65 65 5f 63 75 72 73 6f 72 20 24 44 42 20  tree_cursor $DB 
2a00: 24 72 6f 6f 74 70 61 67 65 20 30 5d 0a 20 20 66  $rootpage 0].  f
2a10: 6f 72 20 7b 62 74 72 65 65 5f 66 69 72 73 74 20  or {btree_first 
2a20: 24 63 73 72 7d 20 7b 21 5b 62 74 72 65 65 5f 65  $csr} {![btree_e
2a30: 6f 66 20 24 63 73 72 5d 7d 20 7b 62 74 72 65 65  of $csr]} {btree
2a40: 5f 6e 65 78 74 20 24 63 73 72 7d 20 7b 0a 20 20  _next $csr} {.  
2a50: 20 20 69 6e 63 72 20 63 6e 74 5f 6c 65 61 66 5f    incr cnt_leaf_
2a60: 65 6e 74 72 79 0a 0a 20 20 20 20 23 20 52 65 74  entry..    # Ret
2a70: 72 69 65 76 65 20 69 6e 66 6f 72 6d 61 74 69 6f  rieve informatio
2a80: 6e 20 61 62 6f 75 74 20 74 68 65 20 65 6e 74 72  n about the entr
2a90: 79 20 74 68 65 20 62 74 72 65 65 2d 63 75 72 73  y the btree-curs
2aa0: 6f 72 20 70 6f 69 6e 74 73 20 74 6f 20 69 6e 74  or points to int
2ab0: 6f 0a 20 20 20 20 23 20 74 68 65 20 61 72 72 61  o.    # the arra
2ac0: 79 20 76 61 72 69 61 62 6c 65 20 24 63 69 20 28  y variable $ci (
2ad0: 63 75 72 73 6f 72 20 69 6e 66 6f 29 2e 0a 20 20  cursor info)..  
2ae0: 20 20 23 0a 20 20 20 20 63 75 72 73 6f 72 5f 69    #.    cursor_i
2af0: 6e 66 6f 20 63 69 20 24 63 73 72 0a 0a 20 20 20  nfo ci $csr..   
2b00: 20 23 20 43 68 65 63 6b 20 69 66 20 74 68 65 20   # Check if the 
2b10: 70 61 79 6c 6f 61 64 20 6f 66 20 74 68 69 73 20  payload of this 
2b20: 65 6e 74 72 79 20 69 73 20 67 72 65 61 74 65 72  entry is greater
2b30: 20 74 68 61 6e 20 74 68 65 20 63 75 72 72 65 6e   than the curren
2b40: 74 20 0a 20 20 20 20 23 20 24 6d 78 5f 70 61 79  t .    # $mx_pay
2b50: 6c 6f 61 64 20 73 74 61 74 69 73 74 69 63 20 66  load statistic f
2b60: 6f 72 20 74 68 65 20 74 61 62 6c 65 2e 20 41 6c  or the table. Al
2b70: 73 6f 20 69 6e 63 72 65 61 73 65 20 74 68 65 20  so increase the 
2b80: 24 74 6f 74 61 6c 5f 70 61 79 6c 6f 61 64 0a 20  $total_payload. 
2b90: 20 20 20 23 20 73 74 61 74 69 73 74 69 63 2e 0a     # statistic..
2ba0: 20 20 20 20 23 0a 20 20 20 20 73 65 74 20 70 61      #.    set pa
2bb0: 79 6c 6f 61 64 20 5b 62 74 72 65 65 5f 6b 65 79  yload [btree_key
2bc0: 73 69 7a 65 20 24 63 73 72 5d 0a 20 20 20 20 69  size $csr].    i
2bd0: 66 20 7b 24 70 61 79 6c 6f 61 64 3e 24 6d 78 5f  f {$payload>$mx_
2be0: 70 61 79 6c 6f 61 64 7d 20 7b 73 65 74 20 6d 78  payload} {set mx
2bf0: 5f 70 61 79 6c 6f 61 64 20 24 70 61 79 6c 6f 61  _payload $payloa
2c00: 64 7d 0a 20 20 20 20 69 6e 63 72 20 74 6f 74 61  d}.    incr tota
2c10: 6c 5f 70 61 79 6c 6f 61 64 20 24 70 61 79 6c 6f  l_payload $paylo
2c20: 61 64 0a 0a 20 20 20 20 23 20 49 66 20 74 68 69  ad..    # If thi
2c30: 73 20 65 6e 74 72 79 20 75 73 65 73 20 6f 76 65  s entry uses ove
2c40: 72 66 6c 6f 77 20 70 61 67 65 73 2c 20 74 68 65  rflow pages, the
2c50: 6e 20 75 70 64 61 74 65 20 74 68 65 20 24 63 6e  n update the $cn
2c60: 74 5f 6f 76 66 6c 2c 20 0a 20 20 20 20 23 20 24  t_ovfl, .    # $
2c70: 74 6f 74 61 6c 5f 6f 76 66 6c 2c 20 24 6f 76 66  total_ovfl, $ovf
2c80: 6c 5f 70 61 67 65 73 20 61 6e 64 20 24 75 6e 75  l_pages and $unu
2c90: 73 65 64 5f 6f 76 66 6c 20 73 74 61 74 69 73 74  sed_ovfl statist
2ca0: 69 63 73 2e 0a 20 20 20 20 23 0a 20 20 20 20 73  ics..    #.    s
2cb0: 65 74 20 6f 76 66 6c 20 5b 65 78 70 72 20 7b 24  et ovfl [expr {$
2cc0: 70 61 79 6c 6f 61 64 2d 24 63 69 28 6c 6f 63 61  payload-$ci(loca
2cd0: 6c 5f 70 61 79 6c 6f 61 64 5f 62 79 74 65 73 29  l_payload_bytes)
2ce0: 7d 5d 0a 20 20 20 20 69 66 20 7b 24 6f 76 66 6c  }].    if {$ovfl
2cf0: 7d 20 7b 0a 20 20 20 20 20 20 69 6e 63 72 20 63  } {.      incr c
2d00: 6e 74 5f 6f 76 66 6c 0a 20 20 20 20 20 20 69 6e  nt_ovfl.      in
2d10: 63 72 20 74 6f 74 61 6c 5f 6f 76 66 6c 20 24 6f  cr total_ovfl $o
2d20: 76 66 6c 0a 20 20 20 20 20 20 73 65 74 20 6e 20  vfl.      set n 
2d30: 5b 65 78 70 72 20 7b 69 6e 74 28 63 65 69 6c 28  [expr {int(ceil(
2d40: 24 6f 76 66 6c 2f 28 24 70 61 67 65 53 69 7a 65  $ovfl/($pageSize
2d50: 2d 34 2e 30 29 29 29 7d 5d 0a 20 20 20 20 20 20  -4.0)))}].      
2d60: 69 6e 63 72 20 6f 76 66 6c 5f 70 61 67 65 73 20  incr ovfl_pages 
2d70: 24 6e 0a 20 20 20 20 20 20 69 6e 63 72 20 75 6e  $n.      incr un
2d80: 75 73 65 64 5f 6f 76 66 6c 20 5b 65 78 70 72 20  used_ovfl [expr 
2d90: 7b 24 6e 2a 28 24 70 61 67 65 53 69 7a 65 2d 34  {$n*($pageSize-4
2da0: 29 20 2d 20 24 6f 76 66 6c 7d 5d 0a 20 20 20 20  ) - $ovfl}].    
2db0: 7d 0a 0a 20 20 20 20 23 20 49 66 20 74 68 69 73  }..    # If this
2dc0: 20 69 73 20 74 68 65 20 66 69 72 73 74 20 74 61   is the first ta
2dd0: 62 6c 65 20 65 6e 74 72 79 20 61 6e 61 6c 79 7a  ble entry analyz
2de0: 65 64 20 66 6f 72 20 74 68 65 20 70 61 67 65 2c  ed for the page,
2df0: 20 74 68 65 6e 20 75 70 64 61 74 65 0a 20 20 20   then update.   
2e00: 20 23 20 74 68 65 20 70 61 67 65 2d 72 65 6c 61   # the page-rela
2e10: 74 65 64 20 73 74 61 74 69 73 74 69 63 73 20 24  ted statistics $
2e20: 6c 65 61 66 5f 70 61 67 65 73 20 61 6e 64 20 24  leaf_pages and $
2e30: 75 6e 75 73 65 64 5f 6c 65 61 66 2e 0a 20 20 20  unused_leaf..   
2e40: 20 23 0a 20 20 20 20 69 66 20 7b 21 5b 69 6e 66   #.    if {![inf
2e50: 6f 20 65 78 69 73 74 73 20 73 65 65 6e 28 24 63  o exists seen($c
2e60: 69 28 70 61 67 65 5f 6e 6f 29 29 5d 7d 20 7b 0a  i(page_no))]} {.
2e70: 20 20 20 20 20 20 73 65 74 20 73 65 65 6e 28 24        set seen($
2e80: 63 69 28 70 61 67 65 5f 6e 6f 29 29 20 31 0a 20  ci(page_no)) 1. 
2e90: 20 20 20 20 20 69 6e 63 72 20 6c 65 61 66 5f 70       incr leaf_p
2ea0: 61 67 65 73 0a 20 20 20 20 20 20 69 6e 63 72 20  ages.      incr 
2eb0: 75 6e 75 73 65 64 5f 6c 65 61 66 20 24 63 69 28  unused_leaf $ci(
2ec0: 70 61 67 65 5f 66 72 65 65 62 79 74 65 73 29 0a  page_freebytes).
2ed0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 62 74 72 65      }.  }.  btre
2ee0: 65 5f 63 6c 6f 73 65 5f 63 75 72 73 6f 72 20 24  e_close_cursor $
2ef0: 63 73 72 0a 0a 20 20 23 20 48 61 6e 64 6c 65 20  csr..  # Handle 
2f00: 74 68 65 20 73 70 65 63 69 61 6c 20 63 61 73 65  the special case
2f10: 20 77 68 65 72 65 20 61 20 69 6e 64 65 78 20 63   where a index c
2f20: 6f 6e 74 61 69 6e 73 20 6e 6f 20 64 61 74 61 2e  ontains no data.
2f30: 20 49 6e 20 74 68 69 73 20 63 61 73 65 0a 20 20   In this case.  
2f40: 23 20 61 6c 6c 20 73 74 61 74 69 73 74 69 63 73  # all statistics
2f50: 20 61 72 65 20 7a 65 72 6f 2c 20 65 78 63 65 70   are zero, excep
2f60: 74 20 66 6f 72 20 74 68 65 20 6e 75 6d 62 65 72  t for the number
2f70: 20 6f 66 20 6c 65 61 66 20 70 61 67 65 73 20 28   of leaf pages (
2f80: 31 29 20 61 6e 64 0a 20 20 23 20 74 68 65 20 75  1) and.  # the u
2f90: 6e 75 73 65 64 20 62 79 74 65 73 20 6f 6e 20 6c  nused bytes on l
2fa0: 65 61 66 20 70 61 67 65 73 20 28 24 70 61 67 65  eaf pages ($page
2fb0: 53 69 7a 65 20 2d 20 38 29 2e 0a 20 20 23 0a 20  Size - 8)..  #. 
2fc0: 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 5b 61   if {[llength [a
2fd0: 72 72 61 79 20 6e 61 6d 65 73 20 73 65 65 6e 5d  rray names seen]
2fe0: 5d 3d 3d 30 7d 20 7b 0a 20 20 20 20 73 65 74 20  ]==0} {.    set 
2ff0: 6c 65 61 66 5f 70 61 67 65 73 20 31 0a 20 20 20  leaf_pages 1.   
3000: 20 73 65 74 20 75 6e 75 73 65 64 5f 6c 65 61 66   set unused_leaf
3010: 20 5b 65 78 70 72 20 7b 24 70 61 67 65 53 69 7a   [expr {$pageSiz
3020: 65 2d 38 7d 5d 0a 20 20 7d 0a 0a 20 20 23 20 49  e-8}].  }..  # I
3030: 6e 73 65 72 74 20 74 68 65 20 73 74 61 74 69 73  nsert the statis
3040: 74 69 63 73 20 66 6f 72 20 74 68 65 20 69 6e 64  tics for the ind
3050: 65 78 20 61 6e 61 6c 79 7a 65 64 20 69 6e 74 6f  ex analyzed into
3060: 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 64   the in-memory d
3070: 61 74 61 62 61 73 65 2e 0a 20 20 23 0a 20 20 73  atabase..  #.  s
3080: 65 74 20 73 71 6c 20 22 49 4e 53 45 52 54 20 49  et sql "INSERT I
3090: 4e 54 4f 20 73 70 61 63 65 5f 75 73 65 64 20 56  NTO space_used V
30a0: 41 4c 55 45 53 28 22 0a 20 20 61 70 70 65 6e 64  ALUES(".  append
30b0: 20 73 71 6c 20 5b 71 75 6f 74 65 20 24 6e 61 6d   sql [quote $nam
30c0: 65 5d 0a 20 20 61 70 70 65 6e 64 20 73 71 6c 20  e].  append sql 
30d0: 22 2c 5b 71 75 6f 74 65 20 24 74 62 6c 5f 6e 61  ",[quote $tbl_na
30e0: 6d 65 5d 22 0a 20 20 61 70 70 65 6e 64 20 73 71  me]".  append sq
30f0: 6c 20 22 2c 31 22 0a 20 20 61 70 70 65 6e 64 20  l ",1".  append 
3100: 73 71 6c 20 22 2c 24 63 6e 74 5f 6c 65 61 66 5f  sql ",$cnt_leaf_
3110: 65 6e 74 72 79 22 0a 20 20 61 70 70 65 6e 64 20  entry".  append 
3120: 73 71 6c 20 22 2c 24 63 6e 74 5f 6c 65 61 66 5f  sql ",$cnt_leaf_
3130: 65 6e 74 72 79 22 0a 20 20 61 70 70 65 6e 64 20  entry".  append 
3140: 73 71 6c 20 22 2c 24 74 6f 74 61 6c 5f 70 61 79  sql ",$total_pay
3150: 6c 6f 61 64 22 0a 20 20 61 70 70 65 6e 64 20 73  load".  append s
3160: 71 6c 20 22 2c 24 74 6f 74 61 6c 5f 6f 76 66 6c  ql ",$total_ovfl
3170: 22 0a 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22  ".  append sql "
3180: 2c 24 63 6e 74 5f 6f 76 66 6c 22 0a 20 20 61 70  ,$cnt_ovfl".  ap
3190: 70 65 6e 64 20 73 71 6c 20 22 2c 24 6d 78 5f 70  pend sql ",$mx_p
31a0: 61 79 6c 6f 61 64 22 0a 20 20 61 70 70 65 6e 64  ayload".  append
31b0: 20 73 71 6c 20 22 2c 30 22 0a 20 20 61 70 70 65   sql ",0".  appe
31c0: 6e 64 20 73 71 6c 20 22 2c 24 6c 65 61 66 5f 70  nd sql ",$leaf_p
31d0: 61 67 65 73 22 0a 20 20 61 70 70 65 6e 64 20 73  ages".  append s
31e0: 71 6c 20 22 2c 24 6f 76 66 6c 5f 70 61 67 65 73  ql ",$ovfl_pages
31f0: 22 0a 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22  ".  append sql "
3200: 2c 30 22 0a 20 20 61 70 70 65 6e 64 20 73 71 6c  ,0".  append sql
3210: 20 22 2c 24 75 6e 75 73 65 64 5f 6c 65 61 66 22   ",$unused_leaf"
3220: 0a 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22 2c  .  append sql ",
3230: 24 75 6e 75 73 65 64 5f 6f 76 66 6c 22 0a 20 20  $unused_ovfl".  
3240: 61 70 70 65 6e 64 20 73 71 6c 20 29 3b 0a 20 20  append sql );.  
3250: 6d 65 6d 20 65 76 61 6c 20 24 73 71 6c 0a 7d 0a  mem eval $sql.}.
3260: 0a 23 20 47 65 6e 65 72 61 74 65 20 61 20 73 69  .# Generate a si
3270: 6e 67 6c 65 20 6c 69 6e 65 20 6f 66 20 6f 75 74  ngle line of out
3280: 70 75 74 20 69 6e 20 74 68 65 20 73 74 61 74 69  put in the stati
3290: 73 74 69 63 73 20 73 65 63 74 69 6f 6e 20 6f 66  stics section of
32a0: 20 74 68 65 0a 23 20 72 65 70 6f 72 74 2e 0a 23   the.# report..#
32b0: 0a 70 72 6f 63 20 73 74 61 74 6c 69 6e 65 20 7b  .proc statline {
32c0: 74 69 74 6c 65 20 76 61 6c 75 65 20 7b 65 78 74  title value {ext
32d0: 72 61 20 7b 7d 7d 7d 20 7b 0a 20 20 73 65 74 20  ra {}}} {.  set 
32e0: 6c 65 6e 20 5b 73 74 72 69 6e 67 20 6c 65 6e 67  len [string leng
32f0: 74 68 20 24 74 69 74 6c 65 5d 0a 20 20 73 65 74  th $title].  set
3300: 20 64 6f 74 73 20 5b 73 74 72 69 6e 67 20 72 61   dots [string ra
3310: 6e 67 65 20 7b 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e  nge {...........
3320: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e  ................
3330: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 7d 20 24 6c 65  ...........} $le
3340: 6e 20 65 6e 64 5d 0a 20 20 73 65 74 20 6c 65 6e  n end].  set len
3350: 20 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20   [string length 
3360: 24 76 61 6c 75 65 5d 0a 20 20 73 65 74 20 73 70  $value].  set sp
3370: 32 20 5b 73 74 72 69 6e 67 20 72 61 6e 67 65 20  2 [string range 
3380: 7b 20 20 20 20 20 20 20 20 20 20 7d 20 24 6c 65  {          } $le
3390: 6e 20 65 6e 64 5d 0a 20 20 69 66 20 7b 24 65 78  n end].  if {$ex
33a0: 74 72 61 20 6e 65 20 22 22 7d 20 7b 0a 20 20 20  tra ne ""} {.   
33b0: 20 73 65 74 20 65 78 74 72 61 20 22 20 24 65 78   set extra " $ex
33c0: 74 72 61 22 0a 20 20 7d 0a 20 20 70 75 74 73 20  tra".  }.  puts 
33d0: 22 24 74 69 74 6c 65 24 64 6f 74 73 20 24 76 61  "$title$dots $va
33e0: 6c 75 65 24 73 70 32 24 65 78 74 72 61 22 0a 7d  lue$sp2$extra".}
33f0: 0a 0a 23 20 47 65 6e 65 72 61 74 65 20 61 20 66  ..# Generate a f
3400: 6f 72 6d 61 74 74 65 64 20 70 65 72 63 65 6e 74  ormatted percent
3410: 61 67 65 20 76 61 6c 75 65 20 66 6f 72 20 24 6e  age value for $n
3420: 75 6d 2f 24 64 65 6e 6f 6d 0a 23 0a 70 72 6f 63  um/$denom.#.proc
3430: 20 70 65 72 63 65 6e 74 20 7b 6e 75 6d 20 64 65   percent {num de
3440: 6e 6f 6d 20 7b 6f 66 20 7b 7d 7d 7d 20 7b 0a 20  nom {of {}}} {. 
3450: 20 69 66 20 7b 24 64 65 6e 6f 6d 3d 3d 30 2e 30   if {$denom==0.0
3460: 7d 20 7b 72 65 74 75 72 6e 20 22 22 7d 0a 20 20  } {return ""}.  
3470: 73 65 74 20 76 20 5b 65 78 70 72 20 7b 24 6e 75  set v [expr {$nu
3480: 6d 2a 31 30 30 2e 30 2f 24 64 65 6e 6f 6d 7d 5d  m*100.0/$denom}]
3490: 0a 20 20 73 65 74 20 6f 66 20 7b 7d 0a 20 20 69  .  set of {}.  i
34a0: 66 20 7b 24 76 3d 3d 31 30 30 2e 30 20 7c 7c 20  f {$v==100.0 || 
34b0: 24 76 3c 30 2e 30 30 31 20 7c 7c 20 28 24 76 3e  $v<0.001 || ($v>
34c0: 31 2e 30 20 26 26 20 24 76 3c 39 39 2e 30 29 7d  1.0 && $v<99.0)}
34d0: 20 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 5b 66   {.    return [f
34e0: 6f 72 6d 61 74 20 7b 25 35 2e 31 66 25 25 20 25  ormat {%5.1f%% %
34f0: 73 7d 20 24 76 20 24 6f 66 5d 0a 20 20 7d 20 65  s} $v $of].  } e
3500: 6c 73 65 69 66 20 7b 24 76 3c 30 2e 31 20 7c 7c  lseif {$v<0.1 ||
3510: 20 24 76 3e 39 39 2e 39 7d 20 7b 0a 20 20 20 20   $v>99.9} {.    
3520: 72 65 74 75 72 6e 20 5b 66 6f 72 6d 61 74 20 7b  return [format {
3530: 25 37 2e 33 66 25 25 20 25 73 7d 20 24 76 20 24  %7.3f%% %s} $v $
3540: 6f 66 5d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20  of].  } else {. 
3550: 20 20 20 72 65 74 75 72 6e 20 5b 66 6f 72 6d 61     return [forma
3560: 74 20 7b 25 36 2e 32 66 25 25 20 25 73 7d 20 24  t {%6.2f%% %s} $
3570: 76 20 24 6f 66 5d 0a 20 20 7d 0a 7d 0a 0a 70 72  v $of].  }.}..pr
3580: 6f 63 20 64 69 76 69 64 65 20 7b 6e 75 6d 20 64  oc divide {num d
3590: 65 6e 6f 6d 7d 20 7b 0a 20 20 69 66 20 7b 24 64  enom} {.  if {$d
35a0: 65 6e 6f 6d 3d 3d 30 7d 20 7b 72 65 74 75 72 6e  enom==0} {return
35b0: 20 30 2e 30 7d 0a 20 20 72 65 74 75 72 6e 20 5b   0.0}.  return [
35c0: 66 6f 72 6d 61 74 20 25 2e 32 66 20 5b 65 78 70  format %.2f [exp
35d0: 72 20 64 6f 75 62 6c 65 28 24 6e 75 6d 29 2f 64  r double($num)/d
35e0: 6f 75 62 6c 65 28 24 64 65 6e 6f 6d 29 5d 5d 0a  ouble($denom)]].
35f0: 7d 0a 0a 23 20 47 65 6e 65 72 61 74 65 20 61 20  }..# Generate a 
3600: 73 75 62 72 65 70 6f 72 74 20 74 68 61 74 20 63  subreport that c
3610: 6f 76 65 72 73 20 73 6f 6d 65 20 73 75 62 73 65  overs some subse
3620: 74 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73  t of the databas
3630: 65 2e 0a 23 20 74 68 65 20 24 77 68 65 72 65 20  e..# the $where 
3640: 63 6c 61 75 73 65 20 64 65 74 65 72 6d 69 6e 65  clause determine
3650: 73 20 77 68 69 63 68 20 73 75 62 73 65 74 20 74  s which subset t
3660: 6f 20 61 6e 61 6c 79 7a 65 2e 0a 23 0a 70 72 6f  o analyze..#.pro
3670: 63 20 73 75 62 72 65 70 6f 72 74 20 7b 74 69 74  c subreport {tit
3680: 6c 65 20 77 68 65 72 65 7d 20 7b 0a 20 20 67 6c  le where} {.  gl
3690: 6f 62 61 6c 20 70 61 67 65 53 69 7a 65 20 66 69  obal pageSize fi
36a0: 6c 65 5f 70 67 63 6e 74 0a 0a 20 20 23 20 51 75  le_pgcnt..  # Qu
36b0: 65 72 79 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72  ery the in-memor
36c0: 79 20 64 61 74 61 62 61 73 65 20 66 6f 72 20 74  y database for t
36d0: 68 65 20 73 75 6d 20 6f 66 20 76 61 72 69 6f 75  he sum of variou
36e0: 73 20 73 74 61 74 69 73 74 69 63 73 20 0a 20 20  s statistics .  
36f0: 23 20 66 6f 72 20 74 68 65 20 73 75 62 73 65 74  # for the subset
3700: 20 6f 66 20 74 61 62 6c 65 73 2f 69 6e 64 69 63   of tables/indic
3710: 65 73 20 69 64 65 6e 74 69 66 69 65 64 20 62 79  es identified by
3720: 20 74 68 65 20 57 48 45 52 45 20 63 6c 61 75 73   the WHERE claus
3730: 65 20 69 6e 0a 20 20 23 20 24 77 68 65 72 65 2e  e in.  # $where.
3740: 20 4e 6f 74 65 20 74 68 61 74 20 65 76 65 6e 20   Note that even 
3750: 69 66 20 74 68 65 20 57 48 45 52 45 20 63 6c 61  if the WHERE cla
3760: 75 73 65 20 6d 61 74 63 68 65 73 20 6e 6f 20 72  use matches no r
3770: 6f 77 73 2c 20 74 68 65 0a 20 20 23 20 66 6f 6c  ows, the.  # fol
3780: 6c 6f 77 69 6e 67 20 71 75 65 72 79 20 72 65 74  lowing query ret
3790: 75 72 6e 73 20 65 78 61 63 74 6c 79 20 6f 6e 65  urns exactly one
37a0: 20 72 6f 77 20 28 62 65 63 61 75 73 65 20 69 74   row (because it
37b0: 20 69 73 20 61 6e 20 61 67 67 72 65 67 61 74 65   is an aggregate
37c0: 29 2e 0a 20 20 23 0a 20 20 23 20 54 68 65 20 72  )..  #.  # The r
37d0: 65 73 75 6c 74 73 20 6f 66 20 74 68 65 20 71 75  esults of the qu
37e0: 65 72 79 20 61 72 65 20 73 74 6f 72 65 64 20 64  ery are stored d
37f0: 69 72 65 63 74 6c 79 20 62 79 20 53 51 4c 69 74  irectly by SQLit
3800: 65 20 69 6e 74 6f 20 6c 6f 63 61 6c 20 0a 20 20  e into local .  
3810: 23 20 76 61 72 69 61 62 6c 65 73 20 28 69 2e 65  # variables (i.e
3820: 2e 20 24 6e 65 6e 74 72 79 2c 20 24 6e 6c 65 61  . $nentry, $nlea
3830: 66 20 65 74 63 2e 29 2e 0a 20 20 23 0a 20 20 6d  f etc.)..  #.  m
3840: 65 6d 20 65 76 61 6c 20 22 0a 20 20 20 20 53 45  em eval ".    SE
3850: 4c 45 43 54 0a 20 20 20 20 20 20 69 6e 74 28 73  LECT.      int(s
3860: 75 6d 28 6e 65 6e 74 72 79 29 29 20 41 53 20 6e  um(nentry)) AS n
3870: 65 6e 74 72 79 2c 0a 20 20 20 20 20 20 69 6e 74  entry,.      int
3880: 28 73 75 6d 28 6c 65 61 66 5f 65 6e 74 72 69 65  (sum(leaf_entrie
3890: 73 29 29 20 41 53 20 6e 6c 65 61 66 2c 0a 20 20  s)) AS nleaf,.  
38a0: 20 20 20 20 69 6e 74 28 73 75 6d 28 70 61 79 6c      int(sum(payl
38b0: 6f 61 64 29 29 20 41 53 20 70 61 79 6c 6f 61 64  oad)) AS payload
38c0: 2c 0a 20 20 20 20 20 20 69 6e 74 28 73 75 6d 28  ,.      int(sum(
38d0: 6f 76 66 6c 5f 70 61 79 6c 6f 61 64 29 29 20 41  ovfl_payload)) A
38e0: 53 20 6f 76 66 6c 5f 70 61 79 6c 6f 61 64 2c 0a  S ovfl_payload,.
38f0: 20 20 20 20 20 20 6d 61 78 28 6d 78 5f 70 61 79        max(mx_pay
3900: 6c 6f 61 64 29 20 41 53 20 6d 78 5f 70 61 79 6c  load) AS mx_payl
3910: 6f 61 64 2c 0a 20 20 20 20 20 20 69 6e 74 28 73  oad,.      int(s
3920: 75 6d 28 6f 76 66 6c 5f 63 6e 74 29 29 20 61 73  um(ovfl_cnt)) as
3930: 20 6f 76 66 6c 5f 63 6e 74 2c 0a 20 20 20 20 20   ovfl_cnt,.     
3940: 20 69 6e 74 28 73 75 6d 28 6c 65 61 66 5f 70 61   int(sum(leaf_pa
3950: 67 65 73 29 29 20 41 53 20 6c 65 61 66 5f 70 61  ges)) AS leaf_pa
3960: 67 65 73 2c 0a 20 20 20 20 20 20 69 6e 74 28 73  ges,.      int(s
3970: 75 6d 28 69 6e 74 5f 70 61 67 65 73 29 29 20 41  um(int_pages)) A
3980: 53 20 69 6e 74 5f 70 61 67 65 73 2c 0a 20 20 20  S int_pages,.   
3990: 20 20 20 69 6e 74 28 73 75 6d 28 6f 76 66 6c 5f     int(sum(ovfl_
39a0: 70 61 67 65 73 29 29 20 41 53 20 6f 76 66 6c 5f  pages)) AS ovfl_
39b0: 70 61 67 65 73 2c 0a 20 20 20 20 20 20 69 6e 74  pages,.      int
39c0: 28 73 75 6d 28 6c 65 61 66 5f 75 6e 75 73 65 64  (sum(leaf_unused
39d0: 29 29 20 41 53 20 6c 65 61 66 5f 75 6e 75 73 65  )) AS leaf_unuse
39e0: 64 2c 0a 20 20 20 20 20 20 69 6e 74 28 73 75 6d  d,.      int(sum
39f0: 28 69 6e 74 5f 75 6e 75 73 65 64 29 29 20 41 53  (int_unused)) AS
3a00: 20 69 6e 74 5f 75 6e 75 73 65 64 2c 0a 20 20 20   int_unused,.   
3a10: 20 20 20 69 6e 74 28 73 75 6d 28 6f 76 66 6c 5f     int(sum(ovfl_
3a20: 75 6e 75 73 65 64 29 29 20 41 53 20 6f 76 66 6c  unused)) AS ovfl
3a30: 5f 75 6e 75 73 65 64 0a 20 20 20 20 46 52 4f 4d  _unused.    FROM
3a40: 20 73 70 61 63 65 5f 75 73 65 64 20 57 48 45 52   space_used WHER
3a50: 45 20 24 77 68 65 72 65 22 20 7b 7d 20 7b 7d 0a  E $where" {} {}.
3a60: 0a 20 20 23 20 4f 75 74 70 75 74 20 74 68 65 20  .  # Output the 
3a70: 73 75 62 2d 72 65 70 6f 72 74 20 74 69 74 6c 65  sub-report title
3a80: 2c 20 6e 69 63 65 6c 79 20 64 65 63 6f 72 61 74  , nicely decorat
3a90: 65 64 20 77 69 74 68 20 2a 20 63 68 61 72 61 63  ed with * charac
3aa0: 74 65 72 73 2e 0a 20 20 23 0a 20 20 70 75 74 73  ters..  #.  puts
3ab0: 20 22 22 0a 20 20 73 65 74 20 6c 65 6e 20 5b 73   "".  set len [s
3ac0: 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 74 69  tring length $ti
3ad0: 74 6c 65 5d 0a 20 20 73 65 74 20 73 74 61 72 73  tle].  set stars
3ae0: 20 5b 73 74 72 69 6e 67 20 72 65 70 65 61 74 20   [string repeat 
3af0: 2a 20 5b 65 78 70 72 20 36 35 2d 24 6c 65 6e 5d  * [expr 65-$len]
3b00: 5d 0a 20 20 70 75 74 73 20 22 2a 2a 2a 20 24 74  ].  puts "*** $t
3b10: 69 74 6c 65 20 24 73 74 61 72 73 22 0a 20 20 70  itle $stars".  p
3b20: 75 74 73 20 22 22 0a 0a 20 20 23 20 43 61 6c 63  uts ""..  # Calc
3b30: 75 6c 61 74 65 20 73 74 61 74 69 73 74 69 63 73  ulate statistics
3b40: 20 61 6e 64 20 73 74 6f 72 65 20 74 68 65 20 72   and store the r
3b50: 65 73 75 6c 74 73 20 69 6e 20 54 43 4c 20 76 61  esults in TCL va
3b60: 72 69 61 62 6c 65 73 2c 20 61 73 20 66 6f 6c 6c  riables, as foll
3b70: 6f 77 73 3a 0a 20 20 23 0a 20 20 23 20 74 6f 74  ows:.  #.  # tot
3b80: 61 6c 5f 70 61 67 65 73 3a 20 44 61 74 61 62 61  al_pages: Databa
3b90: 73 65 20 70 61 67 65 73 20 63 6f 6e 73 75 6d 65  se pages consume
3ba0: 64 2e 0a 20 20 23 20 74 6f 74 61 6c 5f 70 61 67  d..  # total_pag
3bb0: 65 73 5f 70 65 72 63 65 6e 74 3a 20 50 61 67 65  es_percent: Page
3bc0: 73 20 63 6f 6e 73 75 6d 65 64 20 61 73 20 61 20  s consumed as a 
3bd0: 70 65 72 63 65 6e 74 61 67 65 20 6f 66 20 74 68  percentage of th
3be0: 65 20 66 69 6c 65 2e 0a 20 20 23 20 73 74 6f 72  e file..  # stor
3bf0: 61 67 65 3a 20 42 79 74 65 73 20 63 6f 6e 73 75  age: Bytes consu
3c00: 6d 65 64 2e 0a 20 20 23 20 70 61 79 6c 6f 61 64  med..  # payload
3c10: 5f 70 65 72 63 65 6e 74 3a 20 50 61 79 6c 6f 61  _percent: Payloa
3c20: 64 20 62 79 74 65 73 20 75 73 65 64 20 61 73 20  d bytes used as 
3c30: 61 20 70 65 72 63 65 6e 74 61 67 65 20 6f 66 20  a percentage of 
3c40: 24 73 74 6f 72 61 67 65 2e 0a 20 20 23 20 74 6f  $storage..  # to
3c50: 74 61 6c 5f 75 6e 75 73 65 64 3a 20 55 6e 75 73  tal_unused: Unus
3c60: 65 64 20 62 79 74 65 73 20 6f 6e 20 70 61 67 65  ed bytes on page
3c70: 73 2e 0a 20 20 23 20 61 76 67 5f 70 61 79 6c 6f  s..  # avg_paylo
3c80: 61 64 3a 20 41 76 65 72 61 67 65 20 70 61 79 6c  ad: Average payl
3c90: 6f 61 64 20 70 65 72 20 62 74 72 65 65 20 65 6e  oad per btree en
3ca0: 74 72 79 2e 0a 20 20 23 20 61 76 67 5f 66 61 6e  try..  # avg_fan
3cb0: 6f 75 74 3a 20 41 76 65 72 61 67 65 20 66 61 6e  out: Average fan
3cc0: 6f 75 74 20 66 6f 72 20 69 6e 74 65 72 6e 61 6c  out for internal
3cd0: 20 70 61 67 65 73 2e 0a 20 20 23 20 61 76 67 5f   pages..  # avg_
3ce0: 75 6e 75 73 65 64 3a 20 41 76 65 72 61 67 65 20  unused: Average 
3cf0: 75 6e 75 73 65 64 20 62 79 74 65 73 20 70 65 72  unused bytes per
3d00: 20 62 74 72 65 65 20 65 6e 74 72 79 2e 0a 20 20   btree entry..  
3d10: 23 20 6f 76 66 6c 5f 63 6e 74 5f 70 65 72 63 65  # ovfl_cnt_perce
3d20: 6e 74 3a 20 50 65 72 63 65 6e 74 61 67 65 20 6f  nt: Percentage o
3d30: 66 20 62 74 72 65 65 20 65 6e 74 72 69 65 73 20  f btree entries 
3d40: 74 68 61 74 20 75 73 65 20 6f 76 65 72 66 6c 6f  that use overflo
3d50: 77 20 70 61 67 65 73 2e 0a 20 20 23 0a 20 20 73  w pages..  #.  s
3d60: 65 74 20 74 6f 74 61 6c 5f 70 61 67 65 73 20 5b  et total_pages [
3d70: 65 78 70 72 20 7b 24 6c 65 61 66 5f 70 61 67 65  expr {$leaf_page
3d80: 73 2b 24 69 6e 74 5f 70 61 67 65 73 2b 24 6f 76  s+$int_pages+$ov
3d90: 66 6c 5f 70 61 67 65 73 7d 5d 0a 20 20 73 65 74  fl_pages}].  set
3da0: 20 74 6f 74 61 6c 5f 70 61 67 65 73 5f 70 65 72   total_pages_per
3db0: 63 65 6e 74 20 5b 70 65 72 63 65 6e 74 20 24 74  cent [percent $t
3dc0: 6f 74 61 6c 5f 70 61 67 65 73 20 24 66 69 6c 65  otal_pages $file
3dd0: 5f 70 67 63 6e 74 5d 0a 20 20 73 65 74 20 73 74  _pgcnt].  set st
3de0: 6f 72 61 67 65 20 5b 65 78 70 72 20 7b 24 74 6f  orage [expr {$to
3df0: 74 61 6c 5f 70 61 67 65 73 2a 24 70 61 67 65 53  tal_pages*$pageS
3e00: 69 7a 65 7d 5d 0a 20 20 73 65 74 20 70 61 79 6c  ize}].  set payl
3e10: 6f 61 64 5f 70 65 72 63 65 6e 74 20 5b 70 65 72  oad_percent [per
3e20: 63 65 6e 74 20 24 70 61 79 6c 6f 61 64 20 24 73  cent $payload $s
3e30: 74 6f 72 61 67 65 20 7b 6f 66 20 73 74 6f 72 61  torage {of stora
3e40: 67 65 20 63 6f 6e 73 75 6d 65 64 7d 5d 0a 20 20  ge consumed}].  
3e50: 73 65 74 20 74 6f 74 61 6c 5f 75 6e 75 73 65 64  set total_unused
3e60: 20 5b 65 78 70 72 20 7b 24 6f 76 66 6c 5f 75 6e   [expr {$ovfl_un
3e70: 75 73 65 64 2b 24 69 6e 74 5f 75 6e 75 73 65 64  used+$int_unused
3e80: 2b 24 6c 65 61 66 5f 75 6e 75 73 65 64 7d 5d 0a  +$leaf_unused}].
3e90: 20 20 73 65 74 20 61 76 67 5f 70 61 79 6c 6f 61    set avg_payloa
3ea0: 64 20 5b 64 69 76 69 64 65 20 24 70 61 79 6c 6f  d [divide $paylo
3eb0: 61 64 20 24 6e 6c 65 61 66 5d 0a 20 20 73 65 74  ad $nleaf].  set
3ec0: 20 61 76 67 5f 75 6e 75 73 65 64 20 5b 64 69 76   avg_unused [div
3ed0: 69 64 65 20 24 74 6f 74 61 6c 5f 75 6e 75 73 65  ide $total_unuse
3ee0: 64 20 24 6e 6c 65 61 66 5d 0a 20 20 69 66 20 7b  d $nleaf].  if {
3ef0: 24 69 6e 74 5f 70 61 67 65 73 3e 30 7d 20 7b 0a  $int_pages>0} {.
3f00: 20 20 20 20 23 20 54 4f 44 4f 3a 20 49 73 20 74      # TODO: Is t
3f10: 68 69 73 20 66 6f 72 6d 75 6c 61 20 63 6f 72 72  his formula corr
3f20: 65 63 74 3f 0a 20 20 20 20 73 65 74 20 6e 54 61  ect?.    set nTa
3f30: 62 20 5b 6d 65 6d 20 65 76 61 6c 20 22 0a 20 20  b [mem eval ".  
3f40: 20 20 20 20 53 45 4c 45 43 54 20 63 6f 75 6e 74      SELECT count
3f50: 28 2a 29 20 46 52 4f 4d 20 28 0a 20 20 20 20 20  (*) FROM (.     
3f60: 20 20 20 20 20 53 45 4c 45 43 54 20 44 49 53 54       SELECT DIST
3f70: 49 4e 43 54 20 74 62 6c 6e 61 6d 65 20 46 52 4f  INCT tblname FRO
3f80: 4d 20 73 70 61 63 65 5f 75 73 65 64 20 57 48 45  M space_used WHE
3f90: 52 45 20 24 77 68 65 72 65 20 41 4e 44 20 69 73  RE $where AND is
3fa0: 5f 69 6e 64 65 78 3d 30 0a 20 20 20 20 20 20 29  _index=0.      )
3fb0: 0a 20 20 20 20 22 5d 0a 20 20 20 20 73 65 74 20  .    "].    set 
3fc0: 61 76 67 5f 66 61 6e 6f 75 74 20 5b 6d 65 6d 20  avg_fanout [mem 
3fd0: 65 76 61 6c 20 22 0a 20 20 20 20 20 20 53 45 4c  eval ".      SEL
3fe0: 45 43 54 20 28 73 75 6d 28 6c 65 61 66 5f 70 61  ECT (sum(leaf_pa
3ff0: 67 65 73 2b 69 6e 74 5f 70 61 67 65 73 29 2d 24  ges+int_pages)-$
4000: 6e 54 61 62 29 2f 73 75 6d 28 69 6e 74 5f 70 61  nTab)/sum(int_pa
4010: 67 65 73 29 20 46 52 4f 4d 20 73 70 61 63 65 5f  ges) FROM space_
4020: 75 73 65 64 0a 20 20 20 20 20 20 20 20 20 20 57  used.          W
4030: 48 45 52 45 20 24 77 68 65 72 65 20 41 4e 44 20  HERE $where AND 
4040: 69 73 5f 69 6e 64 65 78 20 3d 20 30 0a 20 20 20  is_index = 0.   
4050: 20 22 5d 0a 20 20 20 20 73 65 74 20 61 76 67 5f   "].    set avg_
4060: 66 61 6e 6f 75 74 20 5b 66 6f 72 6d 61 74 20 25  fanout [format %
4070: 2e 32 66 20 24 61 76 67 5f 66 61 6e 6f 75 74 5d  .2f $avg_fanout]
4080: 0a 20 20 7d 0a 20 20 73 65 74 20 6f 76 66 6c 5f  .  }.  set ovfl_
4090: 63 6e 74 5f 70 65 72 63 65 6e 74 20 5b 70 65 72  cnt_percent [per
40a0: 63 65 6e 74 20 24 6f 76 66 6c 5f 63 6e 74 20 24  cent $ovfl_cnt $
40b0: 6e 6c 65 61 66 20 7b 6f 66 20 61 6c 6c 20 65 6e  nleaf {of all en
40c0: 74 72 69 65 73 7d 5d 0a 0a 20 20 23 20 50 72 69  tries}]..  # Pri
40d0: 6e 74 20 6f 75 74 20 74 68 65 20 73 75 62 2d 72  nt out the sub-r
40e0: 65 70 6f 72 74 20 73 74 61 74 69 73 74 69 63 73  eport statistics
40f0: 2e 0a 20 20 23 0a 20 20 73 74 61 74 6c 69 6e 65  ..  #.  statline
4100: 20 7b 50 65 72 63 65 6e 74 61 67 65 20 6f 66 20   {Percentage of 
4110: 74 6f 74 61 6c 20 64 61 74 61 62 61 73 65 7d 20  total database} 
4120: 24 74 6f 74 61 6c 5f 70 61 67 65 73 5f 70 65 72  $total_pages_per
4130: 63 65 6e 74 0a 20 20 73 74 61 74 6c 69 6e 65 20  cent.  statline 
4140: 7b 4e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69  {Number of entri
4150: 65 73 7d 20 24 6e 6c 65 61 66 0a 20 20 73 74 61  es} $nleaf.  sta
4160: 74 6c 69 6e 65 20 7b 42 79 74 65 73 20 6f 66 20  tline {Bytes of 
4170: 73 74 6f 72 61 67 65 20 63 6f 6e 73 75 6d 65 64  storage consumed
4180: 7d 20 24 73 74 6f 72 61 67 65 0a 20 20 73 74 61  } $storage.  sta
4190: 74 6c 69 6e 65 20 7b 42 79 74 65 73 20 6f 66 20  tline {Bytes of 
41a0: 70 61 79 6c 6f 61 64 7d 20 24 70 61 79 6c 6f 61  payload} $payloa
41b0: 64 20 24 70 61 79 6c 6f 61 64 5f 70 65 72 63 65  d $payload_perce
41c0: 6e 74 0a 20 20 73 74 61 74 6c 69 6e 65 20 7b 41  nt.  statline {A
41d0: 76 65 72 61 67 65 20 70 61 79 6c 6f 61 64 20 70  verage payload p
41e0: 65 72 20 65 6e 74 72 79 7d 20 24 61 76 67 5f 70  er entry} $avg_p
41f0: 61 79 6c 6f 61 64 0a 20 20 73 74 61 74 6c 69 6e  ayload.  statlin
4200: 65 20 7b 41 76 65 72 61 67 65 20 75 6e 75 73 65  e {Average unuse
4210: 64 20 62 79 74 65 73 20 70 65 72 20 65 6e 74 72  d bytes per entr
4220: 79 7d 20 24 61 76 67 5f 75 6e 75 73 65 64 0a 20  y} $avg_unused. 
4230: 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74   if {[info exist
4240: 73 20 61 76 67 5f 66 61 6e 6f 75 74 5d 7d 20 7b  s avg_fanout]} {
4250: 0a 20 20 20 20 73 74 61 74 6c 69 6e 65 20 7b 41  .    statline {A
4260: 76 65 72 61 67 65 20 66 61 6e 6f 75 74 7d 20 24  verage fanout} $
4270: 61 76 67 5f 66 61 6e 6f 75 74 0a 20 20 7d 0a 20  avg_fanout.  }. 
4280: 20 73 74 61 74 6c 69 6e 65 20 7b 4d 61 78 69 6d   statline {Maxim
4290: 75 6d 20 70 61 79 6c 6f 61 64 20 70 65 72 20 65  um payload per e
42a0: 6e 74 72 79 7d 20 24 6d 78 5f 70 61 79 6c 6f 61  ntry} $mx_payloa
42b0: 64 0a 20 20 73 74 61 74 6c 69 6e 65 20 7b 45 6e  d.  statline {En
42c0: 74 72 69 65 73 20 74 68 61 74 20 75 73 65 20 6f  tries that use o
42d0: 76 65 72 66 6c 6f 77 7d 20 24 6f 76 66 6c 5f 63  verflow} $ovfl_c
42e0: 6e 74 20 24 6f 76 66 6c 5f 63 6e 74 5f 70 65 72  nt $ovfl_cnt_per
42f0: 63 65 6e 74 0a 20 20 69 66 20 7b 24 69 6e 74 5f  cent.  if {$int_
4300: 70 61 67 65 73 3e 30 7d 20 7b 0a 20 20 20 20 73  pages>0} {.    s
4310: 74 61 74 6c 69 6e 65 20 7b 49 6e 64 65 78 20 70  tatline {Index p
4320: 61 67 65 73 20 75 73 65 64 7d 20 24 69 6e 74 5f  ages used} $int_
4330: 70 61 67 65 73 0a 20 20 7d 0a 20 20 73 74 61 74  pages.  }.  stat
4340: 6c 69 6e 65 20 7b 50 72 69 6d 61 72 79 20 70 61  line {Primary pa
4350: 67 65 73 20 75 73 65 64 7d 20 24 6c 65 61 66 5f  ges used} $leaf_
4360: 70 61 67 65 73 0a 20 20 73 74 61 74 6c 69 6e 65  pages.  statline
4370: 20 7b 4f 76 65 72 66 6c 6f 77 20 70 61 67 65 73   {Overflow pages
4380: 20 75 73 65 64 7d 20 24 6f 76 66 6c 5f 70 61 67   used} $ovfl_pag
4390: 65 73 0a 20 20 73 74 61 74 6c 69 6e 65 20 7b 54  es.  statline {T
43a0: 6f 74 61 6c 20 70 61 67 65 73 20 75 73 65 64 7d  otal pages used}
43b0: 20 24 74 6f 74 61 6c 5f 70 61 67 65 73 0a 20 20   $total_pages.  
43c0: 69 66 20 7b 24 69 6e 74 5f 75 6e 75 73 65 64 3e  if {$int_unused>
43d0: 30 7d 20 7b 0a 20 20 20 20 73 65 74 20 69 6e 74  0} {.    set int
43e0: 5f 75 6e 75 73 65 64 5f 70 65 72 63 65 6e 74 20  _unused_percent 
43f0: 5c 0a 20 20 20 20 20 20 20 20 20 5b 70 65 72 63  \.         [perc
4400: 65 6e 74 20 24 69 6e 74 5f 75 6e 75 73 65 64 20  ent $int_unused 
4410: 5b 65 78 70 72 20 7b 24 69 6e 74 5f 70 61 67 65  [expr {$int_page
4420: 73 2a 24 70 61 67 65 53 69 7a 65 7d 5d 20 7b 6f  s*$pageSize}] {o
4430: 66 20 69 6e 64 65 78 20 73 70 61 63 65 7d 5d 0a  f index space}].
4440: 20 20 20 20 73 74 61 74 6c 69 6e 65 20 22 55 6e      statline "Un
4450: 75 73 65 64 20 62 79 74 65 73 20 6f 6e 20 69 6e  used bytes on in
4460: 64 65 78 20 70 61 67 65 73 22 20 24 69 6e 74 5f  dex pages" $int_
4470: 75 6e 75 73 65 64 20 24 69 6e 74 5f 75 6e 75 73  unused $int_unus
4480: 65 64 5f 70 65 72 63 65 6e 74 0a 20 20 7d 0a 20  ed_percent.  }. 
4490: 20 73 74 61 74 6c 69 6e 65 20 22 55 6e 75 73 65   statline "Unuse
44a0: 64 20 62 79 74 65 73 20 6f 6e 20 70 72 69 6d 61  d bytes on prima
44b0: 72 79 20 70 61 67 65 73 22 20 24 6c 65 61 66 5f  ry pages" $leaf_
44c0: 75 6e 75 73 65 64 20 5c 0a 20 20 20 20 20 5b 70  unused \.     [p
44d0: 65 72 63 65 6e 74 20 24 6c 65 61 66 5f 75 6e 75  ercent $leaf_unu
44e0: 73 65 64 20 5b 65 78 70 72 20 7b 24 6c 65 61 66  sed [expr {$leaf
44f0: 5f 70 61 67 65 73 2a 24 70 61 67 65 53 69 7a 65  _pages*$pageSize
4500: 7d 5d 20 7b 6f 66 20 70 72 69 6d 61 72 79 20 73  }] {of primary s
4510: 70 61 63 65 7d 5d 0a 20 20 73 74 61 74 6c 69 6e  pace}].  statlin
4520: 65 20 22 55 6e 75 73 65 64 20 62 79 74 65 73 20  e "Unused bytes 
4530: 6f 6e 20 6f 76 65 72 66 6c 6f 77 20 70 61 67 65  on overflow page
4540: 73 22 20 24 6f 76 66 6c 5f 75 6e 75 73 65 64 20  s" $ovfl_unused 
4550: 5c 0a 20 20 20 20 20 5b 70 65 72 63 65 6e 74 20  \.     [percent 
4560: 24 6f 76 66 6c 5f 75 6e 75 73 65 64 20 5b 65 78  $ovfl_unused [ex
4570: 70 72 20 7b 24 6f 76 66 6c 5f 70 61 67 65 73 2a  pr {$ovfl_pages*
4580: 24 70 61 67 65 53 69 7a 65 7d 5d 20 7b 6f 66 20  $pageSize}] {of 
4590: 6f 76 65 72 66 6c 6f 77 20 73 70 61 63 65 7d 5d  overflow space}]
45a0: 0a 20 20 73 74 61 74 6c 69 6e 65 20 22 55 6e 75  .  statline "Unu
45b0: 73 65 64 20 62 79 74 65 73 20 6f 6e 20 61 6c 6c  sed bytes on all
45c0: 20 70 61 67 65 73 22 20 24 74 6f 74 61 6c 5f 75   pages" $total_u
45d0: 6e 75 73 65 64 20 5c 0a 20 20 20 20 20 20 20 20  nused \.        
45e0: 20 20 20 20 20 20 20 5b 70 65 72 63 65 6e 74 20         [percent 
45f0: 24 74 6f 74 61 6c 5f 75 6e 75 73 65 64 20 24 73  $total_unused $s
4600: 74 6f 72 61 67 65 20 7b 6f 66 20 61 6c 6c 20 73  torage {of all s
4610: 70 61 63 65 7d 5d 0a 20 20 72 65 74 75 72 6e 20  pace}].  return 
4620: 31 0a 7d 0a 0a 23 20 43 61 6c 63 75 6c 61 74 65  1.}..# Calculate
4630: 20 74 68 65 20 6f 76 65 72 68 65 61 64 20 69 6e   the overhead in
4640: 20 70 61 67 65 73 20 63 61 75 73 65 64 20 62 79   pages caused by
4650: 20 61 75 74 6f 2d 76 61 63 75 75 6d 2e 20 0a 23   auto-vacuum. .#
4660: 0a 23 20 54 68 69 73 20 70 72 6f 63 65 64 75 72  .# This procedur
4670: 65 20 63 61 6c 63 75 6c 61 74 65 73 20 61 6e 64  e calculates and
4680: 20 72 65 74 75 72 6e 73 20 74 68 65 20 6e 75 6d   returns the num
4690: 62 65 72 20 6f 66 20 70 61 67 65 73 20 75 73 65  ber of pages use
46a0: 64 20 62 79 20 74 68 65 20 0a 23 20 61 75 74 6f  d by the .# auto
46b0: 2d 76 61 63 75 75 6d 20 27 70 6f 69 6e 74 65 72  -vacuum 'pointer
46c0: 2d 6d 61 70 27 2e 20 49 66 20 74 68 65 20 64 61  -map'. If the da
46d0: 74 61 62 61 73 65 20 64 6f 65 73 20 6e 6f 74 20  tabase does not 
46e0: 73 75 70 70 6f 72 74 20 61 75 74 6f 2d 76 61 63  support auto-vac
46f0: 75 75 6d 2c 0a 23 20 74 68 65 6e 20 30 20 69 73  uum,.# then 0 is
4700: 20 72 65 74 75 72 6e 65 64 2e 20 54 68 65 20 74   returned. The t
4710: 77 6f 20 61 72 67 75 6d 65 6e 74 73 20 61 72 65  wo arguments are
4720: 20 74 68 65 20 73 69 7a 65 20 6f 66 20 74 68 65   the size of the
4730: 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 69   database file i
4740: 6e 0a 23 20 70 61 67 65 73 20 61 6e 64 20 74 68  n.# pages and th
4750: 65 20 70 61 67 65 20 73 69 7a 65 20 75 73 65 64  e page size used
4760: 20 62 79 20 74 68 65 20 64 61 74 61 62 61 73 65   by the database
4770: 20 28 69 6e 20 62 79 74 65 73 29 2e 0a 70 72 6f   (in bytes)..pro
4780: 63 20 61 75 74 6f 76 61 63 75 75 6d 5f 6f 76 65  c autovacuum_ove
4790: 72 68 65 61 64 20 7b 66 69 6c 65 50 61 67 65 73  rhead {filePages
47a0: 20 70 61 67 65 53 69 7a 65 7d 20 7b 0a 0a 20 20   pageSize} {..  
47b0: 23 20 52 65 61 64 20 74 68 65 20 76 61 6c 75 65  # Read the value
47c0: 20 6f 66 20 6d 65 74 61 20 34 2e 20 49 66 20 6e   of meta 4. If n
47d0: 6f 6e 2d 7a 65 72 6f 2c 20 74 68 65 6e 20 74 68  on-zero, then th
47e0: 65 20 64 61 74 61 62 61 73 65 20 73 75 70 70 6f  e database suppo
47f0: 72 74 73 0a 20 20 23 20 61 75 74 6f 2d 76 61 63  rts.  # auto-vac
4800: 75 75 6d 2e 20 49 74 20 77 6f 75 6c 64 20 62 65  uum. It would be
4810: 20 70 6f 73 73 69 62 6c 65 20 74 6f 20 75 73 65   possible to use
4820: 20 22 50 52 41 47 4d 41 20 61 75 74 6f 5f 76 61   "PRAGMA auto_va
4830: 63 75 75 6d 22 20 69 6e 73 74 65 61 64 2c 0a 20  cuum" instead,. 
4840: 20 23 20 62 75 74 20 74 68 61 74 20 77 6f 75 6c   # but that woul
4850: 64 20 6e 6f 74 20 77 6f 72 6b 20 69 66 20 74 68  d not work if th
4860: 65 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 50 52  e SQLITE_OMIT_PR
4870: 41 47 4d 41 20 6d 61 63 72 6f 20 77 61 73 20 64  AGMA macro was d
4880: 65 66 69 6e 65 64 0a 20 20 23 20 77 68 65 6e 20  efined.  # when 
4890: 74 68 65 20 6c 69 62 72 61 72 79 20 77 61 73 20  the library was 
48a0: 62 75 69 6c 74 2e 0a 20 20 73 65 74 20 6d 65 74  built..  set met
48b0: 61 34 20 5b 6c 69 6e 64 65 78 20 5b 62 74 72 65  a4 [lindex [btre
48c0: 65 5f 67 65 74 5f 6d 65 74 61 20 24 3a 3a 44 42  e_get_meta $::DB
48d0: 5d 20 34 5d 0a 0a 20 20 23 20 49 66 20 74 68 65  ] 4]..  # If the
48e0: 20 64 61 74 61 62 61 73 65 20 69 73 20 6e 6f 74   database is not
48f0: 20 61 6e 20 61 75 74 6f 2d 76 61 63 75 75 6d 20   an auto-vacuum 
4900: 64 61 74 61 62 61 73 65 20 6f 72 20 74 68 65 20  database or the 
4910: 66 69 6c 65 20 63 6f 6e 73 69 73 74 73 0a 20 20  file consists.  
4920: 23 20 6f 66 20 6f 6e 65 20 70 61 67 65 20 6f 6e  # of one page on
4930: 6c 79 20 74 68 65 6e 20 74 68 65 72 65 20 69 73  ly then there is
4940: 20 6e 6f 20 6f 76 65 72 68 65 61 64 20 66 6f 72   no overhead for
4950: 20 61 75 74 6f 2d 76 61 63 75 75 6d 2e 20 52 65   auto-vacuum. Re
4960: 74 75 72 6e 20 7a 65 72 6f 2e 0a 20 20 69 66 20  turn zero..  if 
4970: 7b 30 3d 3d 24 6d 65 74 61 34 20 7c 7c 20 24 66  {0==$meta4 || $f
4980: 69 6c 65 50 61 67 65 73 3d 3d 31 7d 20 7b 0a 20  ilePages==1} {. 
4990: 20 20 20 72 65 74 75 72 6e 20 30 0a 20 20 7d 0a     return 0.  }.
49a0: 0a 20 20 23 20 54 68 65 20 6e 75 6d 62 65 72 20  .  # The number 
49b0: 6f 66 20 65 6e 74 72 69 65 73 20 6f 6e 20 65 61  of entries on ea
49c0: 63 68 20 70 6f 69 6e 74 65 72 20 6d 61 70 20 70  ch pointer map p
49d0: 61 67 65 2e 20 54 68 65 20 6c 61 79 6f 75 74 20  age. The layout 
49e0: 6f 66 20 74 68 65 0a 20 20 23 20 64 61 74 61 62  of the.  # datab
49f0: 61 73 65 20 66 69 6c 65 20 69 73 20 6f 6e 65 20  ase file is one 
4a00: 70 6f 69 6e 74 65 72 2d 6d 61 70 20 70 61 67 65  pointer-map page
4a10: 2c 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20 24 70  , followed by $p
4a20: 74 72 73 50 65 72 50 61 67 65 20 6f 74 68 65 72  trsPerPage other
4a30: 0a 20 20 23 20 70 61 67 65 73 2c 20 66 6f 6c 6c  .  # pages, foll
4a40: 6f 77 65 64 20 62 79 20 61 20 70 6f 69 6e 74 65  owed by a pointe
4a50: 72 2d 6d 61 70 20 70 61 67 65 20 65 74 63 2e 20  r-map page etc. 
4a60: 54 68 65 20 66 69 72 73 74 20 70 6f 69 6e 74 65  The first pointe
4a70: 72 2d 6d 61 70 20 70 61 67 65 0a 20 20 23 20 69  r-map page.  # i
4a80: 73 20 74 68 65 20 73 65 63 6f 6e 64 20 70 61 67  s the second pag
4a90: 65 20 6f 66 20 74 68 65 20 66 69 6c 65 20 6f 76  e of the file ov
4aa0: 65 72 61 6c 6c 2e 0a 20 20 73 65 74 20 70 74 72  erall..  set ptr
4ab0: 73 50 65 72 50 61 67 65 20 5b 65 78 70 72 20 64  sPerPage [expr d
4ac0: 6f 75 62 6c 65 28 24 70 61 67 65 53 69 7a 65 2f  ouble($pageSize/
4ad0: 35 29 5d 0a 0a 20 20 23 20 52 65 74 75 72 6e 20  5)]..  # Return 
4ae0: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 6f  the number of po
4af0: 69 6e 74 65 72 20 6d 61 70 20 70 61 67 65 73 20  inter map pages 
4b00: 69 6e 20 74 68 65 20 64 61 74 61 62 61 73 65 2e  in the database.
4b10: 0a 20 20 72 65 74 75 72 6e 20 5b 65 78 70 72 20  .  return [expr 
4b20: 69 6e 74 28 63 65 69 6c 28 20 28 24 66 69 6c 65  int(ceil( ($file
4b30: 50 61 67 65 73 2d 31 2e 30 29 2f 28 24 70 74 72  Pages-1.0)/($ptr
4b40: 73 50 65 72 50 61 67 65 2b 31 2e 30 29 20 29 29  sPerPage+1.0) ))
4b50: 5d 0a 7d 0a 0a 0a 23 20 43 61 6c 63 75 6c 61 74  ].}...# Calculat
4b60: 65 20 74 68 65 20 73 75 6d 6d 61 72 79 20 73 74  e the summary st
4b70: 61 74 69 73 74 69 63 73 20 66 6f 72 20 74 68 65  atistics for the
4b80: 20 64 61 74 61 62 61 73 65 20 61 6e 64 20 73 74   database and st
4b90: 6f 72 65 20 74 68 65 20 72 65 73 75 6c 74 73 0a  ore the results.
4ba0: 23 20 69 6e 20 54 43 4c 20 76 61 72 69 61 62 6c  # in TCL variabl
4bb0: 65 73 2e 20 54 68 65 79 20 61 72 65 20 6f 75 74  es. They are out
4bc0: 70 75 74 20 62 65 6c 6f 77 2e 20 56 61 72 69 61  put below. Varia
4bd0: 62 6c 65 73 20 61 72 65 20 61 73 20 66 6f 6c 6c  bles are as foll
4be0: 6f 77 73 3a 0a 23 0a 23 20 70 61 67 65 53 69 7a  ows:.#.# pageSiz
4bf0: 65 3a 20 20 20 20 20 20 53 69 7a 65 20 6f 66 20  e:      Size of 
4c00: 65 61 63 68 20 70 61 67 65 20 69 6e 20 62 79 74  each page in byt
4c10: 65 73 2e 0a 23 20 66 69 6c 65 5f 62 79 74 65 73  es..# file_bytes
4c20: 3a 20 20 20 20 46 69 6c 65 20 73 69 7a 65 20 69  :    File size i
4c30: 6e 20 62 79 74 65 73 2e 0a 23 20 66 69 6c 65 5f  n bytes..# file_
4c40: 70 67 63 6e 74 3a 20 20 20 20 4e 75 6d 62 65 72  pgcnt:    Number
4c50: 20 6f 66 20 70 61 67 65 73 20 69 6e 20 74 68 65   of pages in the
4c60: 20 66 69 6c 65 2e 0a 23 20 66 69 6c 65 5f 70 67   file..# file_pg
4c70: 63 6e 74 32 3a 20 20 20 4e 75 6d 62 65 72 20 6f  cnt2:   Number o
4c80: 66 20 70 61 67 65 73 20 69 6e 20 74 68 65 20 66  f pages in the f
4c90: 69 6c 65 20 28 63 61 6c 63 75 6c 61 74 65 64 29  ile (calculated)
4ca0: 2e 0a 23 20 61 76 5f 70 67 63 6e 74 3a 20 20 20  ..# av_pgcnt:   
4cb0: 20 20 20 50 61 67 65 73 20 63 6f 6e 73 75 6d 65     Pages consume
4cc0: 64 20 62 79 20 74 68 65 20 61 75 74 6f 2d 76 61  d by the auto-va
4cd0: 63 75 75 6d 20 70 6f 69 6e 74 65 72 2d 6d 61 70  cuum pointer-map
4ce0: 2e 0a 23 20 61 76 5f 70 65 72 63 65 6e 74 3a 20  ..# av_percent: 
4cf0: 20 20 20 50 65 72 63 65 6e 74 61 67 65 20 6f 66     Percentage of
4d00: 20 74 68 65 20 66 69 6c 65 20 63 6f 6e 73 75 6d   the file consum
4d10: 65 64 20 62 79 20 61 75 74 6f 2d 76 61 63 75 75  ed by auto-vacuu
4d20: 6d 20 70 6f 69 6e 74 65 72 2d 6d 61 70 2e 0a 23  m pointer-map..#
4d30: 20 69 6e 75 73 65 5f 70 67 63 6e 74 3a 20 20 20   inuse_pgcnt:   
4d40: 44 61 74 61 20 70 61 67 65 73 20 69 6e 20 74 68  Data pages in th
4d50: 65 20 66 69 6c 65 2e 0a 23 20 69 6e 75 73 65 5f  e file..# inuse_
4d60: 70 65 72 63 65 6e 74 3a 20 50 65 72 63 65 6e 74  percent: Percent
4d70: 61 67 65 20 6f 66 20 70 61 67 65 73 20 75 73 65  age of pages use
4d80: 64 20 74 6f 20 73 74 6f 72 65 20 64 61 74 61 2e  d to store data.
4d90: 0a 23 20 66 72 65 65 5f 70 67 63 6e 74 3a 20 20  .# free_pgcnt:  
4da0: 20 20 46 72 65 65 20 70 61 67 65 73 20 63 61 6c    Free pages cal
4db0: 63 75 6c 61 74 65 64 20 61 73 20 28 3c 74 6f 74  culated as (<tot
4dc0: 61 6c 20 70 61 67 65 73 3e 20 2d 20 3c 69 6e 2d  al pages> - <in-
4dd0: 75 73 65 20 70 61 67 65 73 3e 29 0a 23 20 66 72  use pages>).# fr
4de0: 65 65 5f 70 67 63 6e 74 32 3a 20 20 20 46 72 65  ee_pgcnt2:   Fre
4df0: 65 20 70 61 67 65 73 20 69 6e 20 74 68 65 20 66  e pages in the f
4e00: 69 6c 65 20 61 63 63 6f 72 64 69 6e 67 20 74 6f  ile according to
4e10: 20 74 68 65 20 66 69 6c 65 20 68 65 61 64 65 72   the file header
4e20: 2e 0a 23 20 66 72 65 65 5f 70 65 72 63 65 6e 74  ..# free_percent
4e30: 3a 20 20 50 65 72 63 65 6e 74 61 67 65 20 6f 66  :  Percentage of
4e40: 20 66 69 6c 65 20 63 6f 6e 73 75 6d 65 64 20 62   file consumed b
4e50: 79 20 66 72 65 65 20 70 61 67 65 73 20 28 63 61  y free pages (ca
4e60: 6c 63 75 6c 61 74 65 64 29 2e 0a 23 20 66 72 65  lculated)..# fre
4e70: 65 5f 70 65 72 63 65 6e 74 32 3a 20 50 65 72 63  e_percent2: Perc
4e80: 65 6e 74 61 67 65 20 6f 66 20 66 69 6c 65 20 63  entage of file c
4e90: 6f 6e 73 75 6d 65 64 20 62 79 20 66 72 65 65 20  onsumed by free 
4ea0: 70 61 67 65 73 20 28 68 65 61 64 65 72 29 2e 0a  pages (header)..
4eb0: 23 20 6e 74 61 62 6c 65 3a 20 20 20 20 20 20 20  # ntable:       
4ec0: 20 4e 75 6d 62 65 72 20 6f 66 20 74 61 62 6c 65   Number of table
4ed0: 73 20 69 6e 20 74 68 65 20 64 62 2e 0a 23 20 6e  s in the db..# n
4ee0: 69 6e 64 65 78 3a 20 20 20 20 20 20 20 20 4e 75  index:        Nu
4ef0: 6d 62 65 72 20 6f 66 20 69 6e 64 69 63 65 73 20  mber of indices 
4f00: 69 6e 20 74 68 65 20 64 62 2e 0a 23 20 6e 61 75  in the db..# nau
4f10: 74 6f 69 6e 64 65 78 3a 20 20 20 20 4e 75 6d 62  toindex:    Numb
4f20: 65 72 20 6f 66 20 69 6e 64 69 63 65 73 20 63 72  er of indices cr
4f30: 65 61 74 65 64 20 61 75 74 6f 6d 61 74 69 63 61  eated automatica
4f40: 6c 6c 79 2e 0a 23 20 6e 6d 61 6e 69 6e 64 65 78  lly..# nmanindex
4f50: 3a 20 20 20 20 20 4e 75 6d 62 65 72 20 6f 66 20  :     Number of 
4f60: 69 6e 64 69 63 65 73 20 63 72 65 61 74 65 64 20  indices created 
4f70: 6d 61 6e 75 61 6c 6c 79 2e 0a 23 20 75 73 65 72  manually..# user
4f80: 5f 70 61 79 6c 6f 61 64 3a 20 20 4e 75 6d 62 65  _payload:  Numbe
4f90: 72 20 6f 66 20 62 79 74 65 73 20 6f 66 20 70 61  r of bytes of pa
4fa0: 79 6c 6f 61 64 20 69 6e 20 74 61 62 6c 65 20 62  yload in table b
4fb0: 74 72 65 65 73 20 0a 23 20 20 20 20 20 20 20 20  trees .#        
4fc0: 20 20 20 20 20 20 20 20 28 6e 6f 74 20 69 6e 63          (not inc
4fd0: 6c 75 64 69 6e 67 20 73 71 6c 69 74 65 5f 6d 61  luding sqlite_ma
4fe0: 73 74 65 72 29 0a 23 20 75 73 65 72 5f 70 65 72  ster).# user_per
4ff0: 63 65 6e 74 3a 20 20 24 75 73 65 72 5f 70 61 79  cent:  $user_pay
5000: 6c 6f 61 64 20 61 73 20 61 20 70 65 72 63 65 6e  load as a percen
5010: 74 61 67 65 20 6f 66 20 74 6f 74 61 6c 20 66 69  tage of total fi
5020: 6c 65 20 73 69 7a 65 2e 0a 0a 73 65 74 20 66 69  le size...set fi
5030: 6c 65 5f 62 79 74 65 73 20 20 5b 66 69 6c 65 20  le_bytes  [file 
5040: 73 69 7a 65 20 24 66 69 6c 65 5f 74 6f 5f 61 6e  size $file_to_an
5050: 61 6c 79 7a 65 5d 0a 73 65 74 20 66 69 6c 65 5f  alyze].set file_
5060: 70 67 63 6e 74 20 20 5b 65 78 70 72 20 7b 24 66  pgcnt  [expr {$f
5070: 69 6c 65 5f 62 79 74 65 73 2f 24 70 61 67 65 53  ile_bytes/$pageS
5080: 69 7a 65 7d 5d 0a 0a 73 65 74 20 61 76 5f 70 67  ize}]..set av_pg
5090: 63 6e 74 20 20 20 20 5b 61 75 74 6f 76 61 63 75  cnt    [autovacu
50a0: 75 6d 5f 6f 76 65 72 68 65 61 64 20 24 66 69 6c  um_overhead $fil
50b0: 65 5f 70 67 63 6e 74 20 24 70 61 67 65 53 69 7a  e_pgcnt $pageSiz
50c0: 65 5d 0a 73 65 74 20 61 76 5f 70 65 72 63 65 6e  e].set av_percen
50d0: 74 20 20 5b 70 65 72 63 65 6e 74 20 24 61 76 5f  t  [percent $av_
50e0: 70 67 63 6e 74 20 24 66 69 6c 65 5f 70 67 63 6e  pgcnt $file_pgcn
50f0: 74 5d 0a 0a 73 65 74 20 73 71 6c 20 7b 53 45 4c  t]..set sql {SEL
5100: 45 43 54 20 73 75 6d 28 6c 65 61 66 5f 70 61 67  ECT sum(leaf_pag
5110: 65 73 2b 69 6e 74 5f 70 61 67 65 73 2b 6f 76 66  es+int_pages+ovf
5120: 6c 5f 70 61 67 65 73 29 20 46 52 4f 4d 20 73 70  l_pages) FROM sp
5130: 61 63 65 5f 75 73 65 64 7d 0a 73 65 74 20 69 6e  ace_used}.set in
5140: 75 73 65 5f 70 67 63 6e 74 20 20 20 5b 65 78 70  use_pgcnt   [exp
5150: 72 20 69 6e 74 28 5b 6d 65 6d 20 65 76 61 6c 20  r int([mem eval 
5160: 24 73 71 6c 5d 29 5d 0a 73 65 74 20 69 6e 75 73  $sql])].set inus
5170: 65 5f 70 65 72 63 65 6e 74 20 5b 70 65 72 63 65  e_percent [perce
5180: 6e 74 20 24 69 6e 75 73 65 5f 70 67 63 6e 74 20  nt $inuse_pgcnt 
5190: 24 66 69 6c 65 5f 70 67 63 6e 74 5d 0a 0a 73 65  $file_pgcnt]..se
51a0: 74 20 66 72 65 65 5f 70 67 63 6e 74 20 20 20 20  t free_pgcnt    
51b0: 5b 65 78 70 72 20 24 66 69 6c 65 5f 70 67 63 6e  [expr $file_pgcn
51c0: 74 2d 24 69 6e 75 73 65 5f 70 67 63 6e 74 2d 24  t-$inuse_pgcnt-$
51d0: 61 76 5f 70 67 63 6e 74 5d 0a 73 65 74 20 66 72  av_pgcnt].set fr
51e0: 65 65 5f 70 65 72 63 65 6e 74 20 20 5b 70 65 72  ee_percent  [per
51f0: 63 65 6e 74 20 24 66 72 65 65 5f 70 67 63 6e 74  cent $free_pgcnt
5200: 20 24 66 69 6c 65 5f 70 67 63 6e 74 5d 0a 73 65   $file_pgcnt].se
5210: 74 20 66 72 65 65 5f 70 67 63 6e 74 32 20 20 20  t free_pgcnt2   
5220: 5b 6c 69 6e 64 65 78 20 5b 62 74 72 65 65 5f 67  [lindex [btree_g
5230: 65 74 5f 6d 65 74 61 20 24 44 42 5d 20 30 5d 0a  et_meta $DB] 0].
5240: 73 65 74 20 66 72 65 65 5f 70 65 72 63 65 6e 74  set free_percent
5250: 32 20 5b 70 65 72 63 65 6e 74 20 24 66 72 65 65  2 [percent $free
5260: 5f 70 67 63 6e 74 32 20 24 66 69 6c 65 5f 70 67  _pgcnt2 $file_pg
5270: 63 6e 74 5d 0a 0a 73 65 74 20 66 69 6c 65 5f 70  cnt]..set file_p
5280: 67 63 6e 74 32 20 5b 65 78 70 72 20 7b 24 69 6e  gcnt2 [expr {$in
5290: 75 73 65 5f 70 67 63 6e 74 2b 24 66 72 65 65 5f  use_pgcnt+$free_
52a0: 70 67 63 6e 74 32 2b 24 61 76 5f 70 67 63 6e 74  pgcnt2+$av_pgcnt
52b0: 7d 5d 0a 0a 73 65 74 20 6e 74 61 62 6c 65 20 5b  }]..set ntable [
52c0: 64 62 20 65 76 61 6c 20 7b 53 45 4c 45 43 54 20  db eval {SELECT 
52d0: 63 6f 75 6e 74 28 2a 29 2b 31 20 46 52 4f 4d 20  count(*)+1 FROM 
52e0: 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48  sqlite_master WH
52f0: 45 52 45 20 74 79 70 65 3d 27 74 61 62 6c 65 27  ERE type='table'
5300: 7d 5d 0a 73 65 74 20 6e 69 6e 64 65 78 20 5b 64  }].set nindex [d
5310: 62 20 65 76 61 6c 20 7b 53 45 4c 45 43 54 20 63  b eval {SELECT c
5320: 6f 75 6e 74 28 2a 29 20 46 52 4f 4d 20 73 71 6c  ount(*) FROM sql
5330: 69 74 65 5f 6d 61 73 74 65 72 20 57 48 45 52 45  ite_master WHERE
5340: 20 74 79 70 65 3d 27 69 6e 64 65 78 27 7d 5d 0a   type='index'}].
5350: 73 65 74 20 73 71 6c 20 7b 53 45 4c 45 43 54 20  set sql {SELECT 
5360: 63 6f 75 6e 74 28 2a 29 20 46 52 4f 4d 20 73 71  count(*) FROM sq
5370: 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48 45 52  lite_master WHER
5380: 45 20 6e 61 6d 65 20 4c 49 4b 45 20 27 73 71 6c  E name LIKE 'sql
5390: 69 74 65 5f 61 75 74 6f 69 6e 64 65 78 25 27 7d  ite_autoindex%'}
53a0: 0a 73 65 74 20 6e 61 75 74 6f 69 6e 64 65 78 20  .set nautoindex 
53b0: 5b 64 62 20 65 76 61 6c 20 24 73 71 6c 5d 0a 73  [db eval $sql].s
53c0: 65 74 20 6e 6d 61 6e 69 6e 64 65 78 20 5b 65 78  et nmanindex [ex
53d0: 70 72 20 7b 24 6e 69 6e 64 65 78 2d 24 6e 61 75  pr {$nindex-$nau
53e0: 74 6f 69 6e 64 65 78 7d 5d 0a 0a 23 20 73 65 74  toindex}]..# set
53f0: 20 74 6f 74 61 6c 5f 70 61 79 6c 6f 61 64 20 5b   total_payload [
5400: 6d 65 6d 20 65 76 61 6c 20 22 53 45 4c 45 43 54  mem eval "SELECT
5410: 20 73 75 6d 28 70 61 79 6c 6f 61 64 29 20 46 52   sum(payload) FR
5420: 4f 4d 20 73 70 61 63 65 5f 75 73 65 64 22 5d 0a  OM space_used"].
5430: 73 65 74 20 75 73 65 72 5f 70 61 79 6c 6f 61 64  set user_payload
5440: 20 5b 6d 65 6d 20 6f 6e 65 20 7b 53 45 4c 45 43   [mem one {SELEC
5450: 54 20 69 6e 74 28 73 75 6d 28 70 61 79 6c 6f 61  T int(sum(payloa
5460: 64 29 29 20 46 52 4f 4d 20 73 70 61 63 65 5f 75  d)) FROM space_u
5470: 73 65 64 0a 20 20 20 20 20 57 48 45 52 45 20 4e  sed.     WHERE N
5480: 4f 54 20 69 73 5f 69 6e 64 65 78 20 41 4e 44 20  OT is_index AND 
5490: 6e 61 6d 65 20 4e 4f 54 20 4c 49 4b 45 20 27 73  name NOT LIKE 's
54a0: 71 6c 69 74 65 5f 6d 61 73 74 65 72 27 7d 5d 0a  qlite_master'}].
54b0: 73 65 74 20 75 73 65 72 5f 70 65 72 63 65 6e 74  set user_percent
54c0: 20 5b 70 65 72 63 65 6e 74 20 24 75 73 65 72 5f   [percent $user_
54d0: 70 61 79 6c 6f 61 64 20 24 66 69 6c 65 5f 62 79  payload $file_by
54e0: 74 65 73 5d 0a 0a 23 20 4f 75 74 70 75 74 20 74  tes]..# Output t
54f0: 68 65 20 73 75 6d 6d 61 72 79 20 73 74 61 74 69  he summary stati
5500: 73 74 69 63 73 20 63 61 6c 63 75 6c 61 74 65 64  stics calculated
5510: 20 61 62 6f 76 65 2e 0a 23 0a 70 75 74 73 20 22   above..#.puts "
5520: 2f 2a 2a 20 44 69 73 6b 2d 53 70 61 63 65 20 55  /** Disk-Space U
5530: 74 69 6c 69 7a 61 74 69 6f 6e 20 52 65 70 6f 72  tilization Repor
5540: 74 20 46 6f 72 20 24 66 69 6c 65 5f 74 6f 5f 61  t For $file_to_a
5550: 6e 61 6c 79 7a 65 22 0a 63 61 74 63 68 20 7b 0a  nalyze".catch {.
5560: 20 20 70 75 74 73 20 22 2a 2a 2a 20 41 73 20 6f    puts "*** As o
5570: 66 20 5b 63 6c 6f 63 6b 20 66 6f 72 6d 61 74 20  f [clock format 
5580: 5b 63 6c 6f 63 6b 20 73 65 63 6f 6e 64 73 5d 20  [clock seconds] 
5590: 2d 66 6f 72 6d 61 74 20 7b 25 59 2d 25 62 2d 25  -format {%Y-%b-%
55a0: 64 20 25 48 3a 25 4d 3a 25 53 7d 5d 22 0a 7d 0a  d %H:%M:%S}]".}.
55b0: 70 75 74 73 20 22 22 0a 73 74 61 74 6c 69 6e 65  puts "".statline
55c0: 20 7b 50 61 67 65 20 73 69 7a 65 20 69 6e 20 62   {Page size in b
55d0: 79 74 65 73 7d 20 24 70 61 67 65 53 69 7a 65 0a  ytes} $pageSize.
55e0: 73 74 61 74 6c 69 6e 65 20 7b 50 61 67 65 73 20  statline {Pages 
55f0: 69 6e 20 74 68 65 20 77 68 6f 6c 65 20 66 69 6c  in the whole fil
5600: 65 20 28 6d 65 61 73 75 72 65 64 29 7d 20 24 66  e (measured)} $f
5610: 69 6c 65 5f 70 67 63 6e 74 0a 73 74 61 74 6c 69  ile_pgcnt.statli
5620: 6e 65 20 7b 50 61 67 65 73 20 69 6e 20 74 68 65  ne {Pages in the
5630: 20 77 68 6f 6c 65 20 66 69 6c 65 20 28 63 61 6c   whole file (cal
5640: 63 75 6c 61 74 65 64 29 7d 20 24 66 69 6c 65 5f  culated)} $file_
5650: 70 67 63 6e 74 32 0a 73 74 61 74 6c 69 6e 65 20  pgcnt2.statline 
5660: 7b 50 61 67 65 73 20 74 68 61 74 20 73 74 6f 72  {Pages that stor
5670: 65 20 64 61 74 61 7d 20 24 69 6e 75 73 65 5f 70  e data} $inuse_p
5680: 67 63 6e 74 20 24 69 6e 75 73 65 5f 70 65 72 63  gcnt $inuse_perc
5690: 65 6e 74 0a 73 74 61 74 6c 69 6e 65 20 7b 50 61  ent.statline {Pa
56a0: 67 65 73 20 6f 6e 20 74 68 65 20 66 72 65 65 6c  ges on the freel
56b0: 69 73 74 20 28 70 65 72 20 68 65 61 64 65 72 29  ist (per header)
56c0: 7d 20 24 66 72 65 65 5f 70 67 63 6e 74 32 20 24  } $free_pgcnt2 $
56d0: 66 72 65 65 5f 70 65 72 63 65 6e 74 32 0a 73 74  free_percent2.st
56e0: 61 74 6c 69 6e 65 20 7b 50 61 67 65 73 20 6f 6e  atline {Pages on
56f0: 20 74 68 65 20 66 72 65 65 6c 69 73 74 20 28 63   the freelist (c
5700: 61 6c 63 75 6c 61 74 65 64 29 7d 20 24 66 72 65  alculated)} $fre
5710: 65 5f 70 67 63 6e 74 20 24 66 72 65 65 5f 70 65  e_pgcnt $free_pe
5720: 72 63 65 6e 74 0a 73 74 61 74 6c 69 6e 65 20 7b  rcent.statline {
5730: 50 61 67 65 73 20 6f 66 20 61 75 74 6f 2d 76 61  Pages of auto-va
5740: 63 75 75 6d 20 6f 76 65 72 68 65 61 64 7d 20 24  cuum overhead} $
5750: 61 76 5f 70 67 63 6e 74 20 24 61 76 5f 70 65 72  av_pgcnt $av_per
5760: 63 65 6e 74 0a 73 74 61 74 6c 69 6e 65 20 7b 4e  cent.statline {N
5770: 75 6d 62 65 72 20 6f 66 20 74 61 62 6c 65 73 20  umber of tables 
5780: 69 6e 20 74 68 65 20 64 61 74 61 62 61 73 65 7d  in the database}
5790: 20 24 6e 74 61 62 6c 65 0a 73 74 61 74 6c 69 6e   $ntable.statlin
57a0: 65 20 7b 4e 75 6d 62 65 72 20 6f 66 20 69 6e 64  e {Number of ind
57b0: 69 63 65 73 7d 20 24 6e 69 6e 64 65 78 0a 73 74  ices} $nindex.st
57c0: 61 74 6c 69 6e 65 20 7b 4e 75 6d 62 65 72 20 6f  atline {Number o
57d0: 66 20 6e 61 6d 65 64 20 69 6e 64 69 63 65 73 7d  f named indices}
57e0: 20 24 6e 6d 61 6e 69 6e 64 65 78 0a 73 74 61 74   $nmanindex.stat
57f0: 6c 69 6e 65 20 7b 41 75 74 6f 6d 61 74 69 63 61  line {Automatica
5800: 6c 6c 79 20 67 65 6e 65 72 61 74 65 64 20 69 6e  lly generated in
5810: 64 69 63 65 73 7d 20 24 6e 61 75 74 6f 69 6e 64  dices} $nautoind
5820: 65 78 0a 73 74 61 74 6c 69 6e 65 20 7b 53 69 7a  ex.statline {Siz
5830: 65 20 6f 66 20 74 68 65 20 66 69 6c 65 20 69 6e  e of the file in
5840: 20 62 79 74 65 73 7d 20 24 66 69 6c 65 5f 62 79   bytes} $file_by
5850: 74 65 73 0a 73 74 61 74 6c 69 6e 65 20 7b 42 79  tes.statline {By
5860: 74 65 73 20 6f 66 20 75 73 65 72 20 70 61 79 6c  tes of user payl
5870: 6f 61 64 20 73 74 6f 72 65 64 7d 20 24 75 73 65  oad stored} $use
5880: 72 5f 70 61 79 6c 6f 61 64 20 24 75 73 65 72 5f  r_payload $user_
5890: 70 65 72 63 65 6e 74 0a 0a 23 20 4f 75 74 70 75  percent..# Outpu
58a0: 74 20 74 61 62 6c 65 20 72 61 6e 6b 69 6e 67 73  t table rankings
58b0: 0a 23 0a 70 75 74 73 20 22 22 0a 70 75 74 73 20  .#.puts "".puts 
58c0: 22 2a 2a 2a 20 50 61 67 65 20 63 6f 75 6e 74 73  "*** Page counts
58d0: 20 66 6f 72 20 61 6c 6c 20 74 61 62 6c 65 73 20   for all tables 
58e0: 77 69 74 68 20 74 68 65 69 72 20 69 6e 64 69 63  with their indic
58f0: 65 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  es *************
5900: 2a 2a 2a 2a 2a 2a 2a 22 0a 70 75 74 73 20 22 22  *******".puts ""
5910: 0a 6d 65 6d 20 65 76 61 6c 20 7b 53 45 4c 45 43  .mem eval {SELEC
5920: 54 20 74 62 6c 6e 61 6d 65 2c 20 63 6f 75 6e 74  T tblname, count
5930: 28 2a 29 20 41 53 20 63 6e 74 2c 20 0a 20 20 20  (*) AS cnt, .   
5940: 20 20 20 20 20 20 20 20 20 20 20 69 6e 74 28 73             int(s
5950: 75 6d 28 69 6e 74 5f 70 61 67 65 73 2b 6c 65 61  um(int_pages+lea
5960: 66 5f 70 61 67 65 73 2b 6f 76 66 6c 5f 70 61 67  f_pages+ovfl_pag
5970: 65 73 29 29 20 41 53 20 73 69 7a 65 0a 20 20 20  es)) AS size.   
5980: 20 20 20 20 20 20 20 46 52 4f 4d 20 73 70 61 63         FROM spac
5990: 65 5f 75 73 65 64 20 47 52 4f 55 50 20 42 59 20  e_used GROUP BY 
59a0: 74 62 6c 6e 61 6d 65 20 4f 52 44 45 52 20 42 59  tblname ORDER BY
59b0: 20 73 69 7a 65 2b 30 20 44 45 53 43 2c 20 74 62   size+0 DESC, tb
59c0: 6c 6e 61 6d 65 7d 20 7b 7d 20 7b 0a 20 20 73 74  lname} {} {.  st
59d0: 61 74 6c 69 6e 65 20 5b 73 74 72 69 6e 67 20 74  atline [string t
59e0: 6f 75 70 70 65 72 20 24 74 62 6c 6e 61 6d 65 5d  oupper $tblname]
59f0: 20 24 73 69 7a 65 20 5b 70 65 72 63 65 6e 74 20   $size [percent 
5a00: 24 73 69 7a 65 20 24 66 69 6c 65 5f 70 67 63 6e  $size $file_pgcn
5a10: 74 5d 0a 7d 0a 0a 23 20 4f 75 74 70 75 74 20 73  t].}..# Output s
5a20: 75 62 72 65 70 6f 72 74 73 0a 23 0a 69 66 20 7b  ubreports.#.if {
5a30: 24 6e 69 6e 64 65 78 3e 30 7d 20 7b 0a 20 20 73  $nindex>0} {.  s
5a40: 75 62 72 65 70 6f 72 74 20 7b 41 6c 6c 20 74 61  ubreport {All ta
5a50: 62 6c 65 73 20 61 6e 64 20 69 6e 64 69 63 65 73  bles and indices
5a60: 7d 20 31 0a 7d 0a 73 75 62 72 65 70 6f 72 74 20  } 1.}.subreport 
5a70: 7b 41 6c 6c 20 74 61 62 6c 65 73 7d 20 7b 4e 4f  {All tables} {NO
5a80: 54 20 69 73 5f 69 6e 64 65 78 7d 0a 69 66 20 7b  T is_index}.if {
5a90: 24 6e 69 6e 64 65 78 3e 30 7d 20 7b 0a 20 20 73  $nindex>0} {.  s
5aa0: 75 62 72 65 70 6f 72 74 20 7b 41 6c 6c 20 69 6e  ubreport {All in
5ab0: 64 69 63 65 73 7d 20 7b 69 73 5f 69 6e 64 65 78  dices} {is_index
5ac0: 7d 0a 7d 0a 66 6f 72 65 61 63 68 20 74 62 6c 20  }.}.foreach tbl 
5ad0: 5b 6d 65 6d 20 65 76 61 6c 20 7b 53 45 4c 45 43  [mem eval {SELEC
5ae0: 54 20 6e 61 6d 65 20 46 52 4f 4d 20 73 70 61 63  T name FROM spac
5af0: 65 5f 75 73 65 64 20 57 48 45 52 45 20 4e 4f 54  e_used WHERE NOT
5b00: 20 69 73 5f 69 6e 64 65 78 0a 20 20 20 20 20 20   is_index.      
5b10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5b20: 20 4f 52 44 45 52 20 42 59 20 6e 61 6d 65 7d 5d   ORDER BY name}]
5b30: 20 7b 0a 20 20 72 65 67 73 75 62 20 27 20 24 74   {.  regsub ' $t
5b40: 62 6c 20 27 27 20 71 6e 0a 20 20 73 65 74 20 6e  bl '' qn.  set n
5b50: 61 6d 65 20 5b 73 74 72 69 6e 67 20 74 6f 75 70  ame [string toup
5b60: 70 65 72 20 24 74 62 6c 5d 0a 20 20 73 65 74 20  per $tbl].  set 
5b70: 6e 20 5b 6d 65 6d 20 65 76 61 6c 20 22 53 45 4c  n [mem eval "SEL
5b80: 45 43 54 20 63 6f 75 6e 74 28 2a 29 20 46 52 4f  ECT count(*) FRO
5b90: 4d 20 73 70 61 63 65 5f 75 73 65 64 20 57 48 45  M space_used WHE
5ba0: 52 45 20 74 62 6c 6e 61 6d 65 3d 27 24 71 6e 27  RE tblname='$qn'
5bb0: 22 5d 0a 20 20 69 66 20 7b 24 6e 3e 31 7d 20 7b  "].  if {$n>1} {
5bc0: 0a 20 20 20 20 73 75 62 72 65 70 6f 72 74 20 22  .    subreport "
5bd0: 54 61 62 6c 65 20 24 6e 61 6d 65 20 61 6e 64 20  Table $name and 
5be0: 61 6c 6c 20 69 74 73 20 69 6e 64 69 63 65 73 22  all its indices"
5bf0: 20 22 74 62 6c 6e 61 6d 65 3d 27 24 71 6e 27 22   "tblname='$qn'"
5c00: 0a 20 20 20 20 73 75 62 72 65 70 6f 72 74 20 22  .    subreport "
5c10: 54 61 62 6c 65 20 24 6e 61 6d 65 20 77 2f 6f 20  Table $name w/o 
5c20: 61 6e 79 20 69 6e 64 69 63 65 73 22 20 22 6e 61  any indices" "na
5c30: 6d 65 3d 27 24 71 6e 27 22 0a 20 20 20 20 73 75  me='$qn'".    su
5c40: 62 72 65 70 6f 72 74 20 22 49 6e 64 69 63 65 73  breport "Indices
5c50: 20 6f 66 20 74 61 62 6c 65 20 24 6e 61 6d 65 22   of table $name"
5c60: 20 22 74 62 6c 6e 61 6d 65 3d 27 24 71 6e 27 20   "tblname='$qn' 
5c70: 41 4e 44 20 69 73 5f 69 6e 64 65 78 22 0a 20 20  AND is_index".  
5c80: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 75 62  } else {.    sub
5c90: 72 65 70 6f 72 74 20 22 54 61 62 6c 65 20 24 6e  report "Table $n
5ca0: 61 6d 65 22 20 22 6e 61 6d 65 3d 27 24 71 6e 27  ame" "name='$qn'
5cb0: 22 0a 20 20 7d 0a 7d 0a 0a 23 20 4f 75 74 70 75  ".  }.}..# Outpu
5cc0: 74 20 69 6e 73 74 72 75 63 74 69 6f 6e 73 20 6f  t instructions o
5cd0: 6e 20 77 68 61 74 20 74 68 65 20 6e 75 6d 62 65  n what the numbe
5ce0: 72 73 20 61 62 6f 76 65 20 6d 65 61 6e 2e 0a 23  rs above mean..#
5cf0: 0a 70 75 74 73 20 7b 0a 2a 2a 2a 20 44 65 66 69  .puts {.*** Defi
5d00: 6e 69 74 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a 2a 2a  nitions ********
5d10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5d20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5d30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 0a  **************..
5d40: 50 61 67 65 20 73 69 7a 65 20 69 6e 20 62 79 74  Page size in byt
5d50: 65 73 0a 0a 20 20 20 20 54 68 65 20 6e 75 6d 62  es..    The numb
5d60: 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20 61  er of bytes in a
5d70: 20 73 69 6e 67 6c 65 20 70 61 67 65 20 6f 66 20   single page of 
5d80: 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
5d90: 65 2e 20 20 0a 20 20 20 20 55 73 75 61 6c 6c 79  e.  .    Usually
5da0: 20 31 30 32 34 2e 0a 0a 4e 75 6d 62 65 72 20 6f   1024...Number o
5db0: 66 20 70 61 67 65 73 20 69 6e 20 74 68 65 20 77  f pages in the w
5dc0: 68 6f 6c 65 20 66 69 6c 65 0a 7d 0a 70 75 74 73  hole file.}.puts
5dd0: 20 5c 0a 22 20 20 20 20 54 68 65 20 6e 75 6d 62   \."    The numb
5de0: 65 72 20 6f 66 20 24 70 61 67 65 53 69 7a 65 2d  er of $pageSize-
5df0: 62 79 74 65 20 70 61 67 65 73 20 74 68 61 74 20  byte pages that 
5e00: 67 6f 20 69 6e 74 6f 20 66 6f 72 6d 69 6e 67 20  go into forming 
5e10: 74 68 65 20 63 6f 6d 70 6c 65 74 65 0a 20 20 20  the complete.   
5e20: 20 64 61 74 61 62 61 73 65 22 0a 70 75 74 73 20   database".puts 
5e30: 5c 0a 7b 0a 50 61 67 65 73 20 74 68 61 74 20 73  \.{.Pages that s
5e40: 74 6f 72 65 20 64 61 74 61 0a 0a 20 20 20 20 54  tore data..    T
5e50: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67  he number of pag
5e60: 65 73 20 74 68 61 74 20 73 74 6f 72 65 20 64 61  es that store da
5e70: 74 61 2c 20 65 69 74 68 65 72 20 61 73 20 70 72  ta, either as pr
5e80: 69 6d 61 72 79 20 42 2a 54 72 65 65 20 70 61 67  imary B*Tree pag
5e90: 65 73 20 6f 72 0a 20 20 20 20 61 73 20 6f 76 65  es or.    as ove
5ea0: 72 66 6c 6f 77 20 70 61 67 65 73 2e 20 20 54 68  rflow pages.  Th
5eb0: 65 20 6e 75 6d 62 65 72 20 61 74 20 74 68 65 20  e number at the 
5ec0: 72 69 67 68 74 20 69 73 20 74 68 65 20 64 61 74  right is the dat
5ed0: 61 20 70 61 67 65 73 20 64 69 76 69 64 65 64 20  a pages divided 
5ee0: 62 79 0a 20 20 20 20 74 68 65 20 74 6f 74 61 6c  by.    the total
5ef0: 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73   number of pages
5f00: 20 69 6e 20 74 68 65 20 66 69 6c 65 2e 0a 0a 50   in the file...P
5f10: 61 67 65 73 20 6f 6e 20 74 68 65 20 66 72 65 65  ages on the free
5f20: 6c 69 73 74 0a 0a 20 20 20 20 54 68 65 20 6e 75  list..    The nu
5f30: 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 74 68  mber of pages th
5f40: 61 74 20 61 72 65 20 6e 6f 74 20 63 75 72 72 65  at are not curre
5f50: 6e 74 6c 79 20 69 6e 20 75 73 65 20 62 75 74 20  ntly in use but 
5f60: 61 72 65 20 72 65 73 65 72 76 65 64 20 66 6f 72  are reserved for
5f70: 0a 20 20 20 20 66 75 74 75 72 65 20 75 73 65 2e  .    future use.
5f80: 20 20 54 68 65 20 70 65 72 63 65 6e 74 61 67 65    The percentage
5f90: 20 61 74 20 74 68 65 20 72 69 67 68 74 20 69 73   at the right is
5fa0: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 66   the number of f
5fb0: 72 65 65 6c 69 73 74 20 70 61 67 65 73 0a 20 20  reelist pages.  
5fc0: 20 20 64 69 76 69 64 65 64 20 62 79 20 74 68 65    divided by the
5fd0: 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66   total number of
5fe0: 20 70 61 67 65 73 20 69 6e 20 74 68 65 20 66 69   pages in the fi
5ff0: 6c 65 2e 0a 0a 50 61 67 65 73 20 6f 66 20 61 75  le...Pages of au
6000: 74 6f 2d 76 61 63 75 75 6d 20 6f 76 65 72 68 65  to-vacuum overhe
6010: 61 64 0a 0a 20 20 20 20 54 68 65 20 6e 75 6d 62  ad..    The numb
6020: 65 72 20 6f 66 20 70 61 67 65 73 20 74 68 61 74  er of pages that
6030: 20 73 74 6f 72 65 20 64 61 74 61 20 75 73 65 64   store data used
6040: 20 62 79 20 74 68 65 20 64 61 74 61 62 61 73 65   by the database
6050: 20 74 6f 20 66 61 63 69 6c 69 74 61 74 65 0a 20   to facilitate. 
6060: 20 20 20 61 75 74 6f 2d 76 61 63 75 75 6d 2e 20     auto-vacuum. 
6070: 54 68 69 73 20 69 73 20 7a 65 72 6f 20 66 6f 72  This is zero for
6080: 20 64 61 74 61 62 61 73 65 73 20 74 68 61 74 20   databases that 
6090: 64 6f 20 6e 6f 74 20 73 75 70 70 6f 72 74 20 61  do not support a
60a0: 75 74 6f 2d 76 61 63 75 75 6d 2e 0a 0a 4e 75 6d  uto-vacuum...Num
60b0: 62 65 72 20 6f 66 20 74 61 62 6c 65 73 20 69 6e  ber of tables in
60c0: 20 74 68 65 20 64 61 74 61 62 61 73 65 0a 0a 20   the database.. 
60d0: 20 20 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66     The number of
60e0: 20 74 61 62 6c 65 73 20 69 6e 20 74 68 65 20 64   tables in the d
60f0: 61 74 61 62 61 73 65 2c 20 69 6e 63 6c 75 64 69  atabase, includi
6100: 6e 67 20 74 68 65 20 53 51 4c 49 54 45 5f 4d 41  ng the SQLITE_MA
6110: 53 54 45 52 20 74 61 62 6c 65 0a 20 20 20 20 75  STER table.    u
6120: 73 65 64 20 74 6f 20 73 74 6f 72 65 20 73 63 68  sed to store sch
6130: 65 6d 61 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 2e  ema information.
6140: 0a 0a 4e 75 6d 62 65 72 20 6f 66 20 69 6e 64 69  ..Number of indi
6150: 63 65 73 0a 0a 20 20 20 20 54 68 65 20 74 6f 74  ces..    The tot
6160: 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 69 6e 64  al number of ind
6170: 69 63 65 73 20 69 6e 20 74 68 65 20 64 61 74 61  ices in the data
6180: 62 61 73 65 2e 0a 0a 4e 75 6d 62 65 72 20 6f 66  base...Number of
6190: 20 6e 61 6d 65 64 20 69 6e 64 69 63 65 73 0a 0a   named indices..
61a0: 20 20 20 20 54 68 65 20 6e 75 6d 62 65 72 20 6f      The number o
61b0: 66 20 69 6e 64 69 63 65 73 20 63 72 65 61 74 65  f indices create
61c0: 64 20 75 73 69 6e 67 20 61 6e 20 65 78 70 6c 69  d using an expli
61d0: 63 69 74 20 43 52 45 41 54 45 20 49 4e 44 45 58  cit CREATE INDEX
61e0: 20 73 74 61 74 65 6d 65 6e 74 2e 0a 0a 41 75 74   statement...Aut
61f0: 6f 6d 61 74 69 63 61 6c 6c 79 20 67 65 6e 65 72  omatically gener
6200: 61 74 65 64 20 69 6e 64 69 63 65 73 0a 0a 20 20  ated indices..  
6210: 20 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66 20    The number of 
6220: 69 6e 64 69 63 65 73 20 75 73 65 64 20 74 6f 20  indices used to 
6230: 69 6d 70 6c 65 6d 65 6e 74 20 50 52 49 4d 41 52  implement PRIMAR
6240: 59 20 4b 45 59 20 6f 72 20 55 4e 49 51 55 45 20  Y KEY or UNIQUE 
6250: 63 6f 6e 73 74 72 61 69 6e 74 73 0a 20 20 20 20  constraints.    
6260: 6f 6e 20 74 61 62 6c 65 73 2e 0a 0a 53 69 7a 65  on tables...Size
6270: 20 6f 66 20 74 68 65 20 66 69 6c 65 20 69 6e 20   of the file in 
6280: 62 79 74 65 73 0a 0a 20 20 20 20 54 68 65 20 74  bytes..    The t
6290: 6f 74 61 6c 20 61 6d 6f 75 6e 74 20 6f 66 20 64  otal amount of d
62a0: 69 73 6b 20 73 70 61 63 65 20 75 73 65 64 20 62  isk space used b
62b0: 79 20 74 68 65 20 65 6e 74 69 72 65 20 64 61 74  y the entire dat
62c0: 61 62 61 73 65 20 66 69 6c 65 73 2e 0a 0a 42 79  abase files...By
62d0: 74 65 73 20 6f 66 20 75 73 65 72 20 70 61 79 6c  tes of user payl
62e0: 6f 61 64 20 73 74 6f 72 65 64 0a 0a 20 20 20 20  oad stored..    
62f0: 54 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72  The total number
6300: 20 6f 66 20 62 79 74 65 73 20 6f 66 20 75 73 65   of bytes of use
6310: 72 20 70 61 79 6c 6f 61 64 20 73 74 6f 72 65 64  r payload stored
6320: 20 69 6e 20 74 68 65 20 64 61 74 61 62 61 73 65   in the database
6330: 2e 20 54 68 65 0a 20 20 20 20 73 63 68 65 6d 61  . The.    schema
6340: 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 69 6e 20   information in 
6350: 74 68 65 20 53 51 4c 49 54 45 5f 4d 41 53 54 45  the SQLITE_MASTE
6360: 52 20 74 61 62 6c 65 20 69 73 20 6e 6f 74 20 63  R table is not c
6370: 6f 75 6e 74 65 64 20 77 68 65 6e 0a 20 20 20 20  ounted when.    
6380: 63 6f 6d 70 75 74 69 6e 67 20 74 68 69 73 20 6e  computing this n
6390: 75 6d 62 65 72 2e 20 20 54 68 65 20 70 65 72 63  umber.  The perc
63a0: 65 6e 74 61 67 65 20 61 74 20 74 68 65 20 72 69  entage at the ri
63b0: 67 68 74 20 73 68 6f 77 73 20 74 68 65 20 70 61  ght shows the pa
63c0: 79 6c 6f 61 64 0a 20 20 20 20 64 69 76 69 64 65  yload.    divide
63d0: 64 20 62 79 20 74 68 65 20 74 6f 74 61 6c 20 66  d by the total f
63e0: 69 6c 65 20 73 69 7a 65 2e 0a 0a 50 65 72 63 65  ile size...Perce
63f0: 6e 74 61 67 65 20 6f 66 20 74 6f 74 61 6c 20 64  ntage of total d
6400: 61 74 61 62 61 73 65 0a 0a 20 20 20 20 54 68 65  atabase..    The
6410: 20 61 6d 6f 75 6e 74 20 6f 66 20 74 68 65 20 63   amount of the c
6420: 6f 6d 70 6c 65 74 65 20 64 61 74 61 62 61 73 65  omplete database
6430: 20 66 69 6c 65 20 74 68 61 74 20 69 73 20 64 65   file that is de
6440: 76 6f 74 65 64 20 74 6f 20 73 74 6f 72 69 6e 67  voted to storing
6450: 0a 20 20 20 20 69 6e 66 6f 72 6d 61 74 69 6f 6e  .    information
6460: 20 64 65 73 63 72 69 62 65 64 20 62 79 20 74 68   described by th
6470: 69 73 20 63 61 74 65 67 6f 72 79 2e 0a 0a 4e 75  is category...Nu
6480: 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73 0a  mber of entries.
6490: 0a 20 20 20 20 54 68 65 20 74 6f 74 61 6c 20 6e  .    The total n
64a0: 75 6d 62 65 72 20 6f 66 20 42 2d 54 72 65 65 20  umber of B-Tree 
64b0: 6b 65 79 2f 76 61 6c 75 65 20 70 61 69 72 73 20  key/value pairs 
64c0: 73 74 6f 72 65 64 20 75 6e 64 65 72 20 74 68 69  stored under thi
64d0: 73 20 63 61 74 65 67 6f 72 79 2e 0a 0a 42 79 74  s category...Byt
64e0: 65 73 20 6f 66 20 73 74 6f 72 61 67 65 20 63 6f  es of storage co
64f0: 6e 73 75 6d 65 64 0a 0a 20 20 20 20 54 68 65 20  nsumed..    The 
6500: 74 6f 74 61 6c 20 61 6d 6f 75 6e 74 20 6f 66 20  total amount of 
6510: 64 69 73 6b 20 73 70 61 63 65 20 72 65 71 75 69  disk space requi
6520: 72 65 64 20 74 6f 20 73 74 6f 72 65 20 61 6c 6c  red to store all
6530: 20 42 2d 54 72 65 65 20 65 6e 74 72 69 65 73 0a   B-Tree entries.
6540: 20 20 20 20 75 6e 64 65 72 20 74 68 69 73 20 63      under this c
6550: 61 74 65 67 6f 72 79 2e 20 20 54 68 65 20 69 73  ategory.  The is
6560: 20 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65   the total numbe
6570: 72 20 6f 66 20 70 61 67 65 73 20 75 73 65 64 20  r of pages used 
6580: 74 69 6d 65 73 0a 20 20 20 20 74 68 65 20 70 61  times.    the pa
6590: 67 65 73 20 73 69 7a 65 2e 0a 0a 42 79 74 65 73  ges size...Bytes
65a0: 20 6f 66 20 70 61 79 6c 6f 61 64 0a 0a 20 20 20   of payload..   
65b0: 20 54 68 65 20 61 6d 6f 75 6e 74 20 6f 66 20 70   The amount of p
65c0: 61 79 6c 6f 61 64 20 73 74 6f 72 65 64 20 75 6e  ayload stored un
65d0: 64 65 72 20 74 68 69 73 20 63 61 74 65 67 6f 72  der this categor
65e0: 79 2e 20 20 50 61 79 6c 6f 61 64 20 69 73 20 74  y.  Payload is t
65f0: 68 65 20 64 61 74 61 0a 20 20 20 20 70 61 72 74  he data.    part
6600: 20 6f 66 20 74 61 62 6c 65 20 65 6e 74 72 69 65   of table entrie
6610: 73 20 61 6e 64 20 74 68 65 20 6b 65 79 20 70 61  s and the key pa
6620: 72 74 20 6f 66 20 69 6e 64 65 78 20 65 6e 74 72  rt of index entr
6630: 69 65 73 2e 20 20 54 68 65 20 70 65 72 63 65 6e  ies.  The percen
6640: 74 61 67 65 0a 20 20 20 20 61 74 20 74 68 65 20  tage.    at the 
6650: 72 69 67 68 74 20 69 73 20 74 68 65 20 62 79 74  right is the byt
6660: 65 73 20 6f 66 20 70 61 79 6c 6f 61 64 20 64 69  es of payload di
6670: 76 69 64 65 64 20 62 79 20 74 68 65 20 62 79 74  vided by the byt
6680: 65 73 20 6f 66 20 73 74 6f 72 61 67 65 20 0a 20  es of storage . 
6690: 20 20 20 63 6f 6e 73 75 6d 65 64 2e 0a 0a 41 76     consumed...Av
66a0: 65 72 61 67 65 20 70 61 79 6c 6f 61 64 20 70 65  erage payload pe
66b0: 72 20 65 6e 74 72 79 0a 0a 20 20 20 20 54 68 65  r entry..    The
66c0: 20 61 76 65 72 61 67 65 20 61 6d 6f 75 6e 74 20   average amount 
66d0: 6f 66 20 70 61 79 6c 6f 61 64 20 6f 6e 20 65 61  of payload on ea
66e0: 63 68 20 65 6e 74 72 79 2e 20 20 54 68 69 73 20  ch entry.  This 
66f0: 69 73 20 6a 75 73 74 20 74 68 65 20 62 79 74 65  is just the byte
6700: 73 20 6f 66 0a 20 20 20 20 70 61 79 6c 6f 61 64  s of.    payload
6710: 20 64 69 76 69 64 65 64 20 62 79 20 74 68 65 20   divided by the 
6720: 6e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65  number of entrie
6730: 73 2e 0a 0a 41 76 65 72 61 67 65 20 75 6e 75 73  s...Average unus
6740: 65 64 20 62 79 74 65 73 20 70 65 72 20 65 6e 74  ed bytes per ent
6750: 72 79 0a 0a 20 20 20 20 54 68 65 20 61 76 65 72  ry..    The aver
6760: 61 67 65 20 61 6d 6f 75 6e 74 20 6f 66 20 66 72  age amount of fr
6770: 65 65 20 73 70 61 63 65 20 72 65 6d 61 69 6e 69  ee space remaini
6780: 6e 67 20 6f 6e 20 61 6c 6c 20 70 61 67 65 73 20  ng on all pages 
6790: 75 6e 64 65 72 20 74 68 69 73 0a 20 20 20 20 63  under this.    c
67a0: 61 74 65 67 6f 72 79 20 6f 6e 20 61 20 70 65 72  ategory on a per
67b0: 2d 65 6e 74 72 79 20 62 61 73 69 73 2e 20 20 54  -entry basis.  T
67c0: 68 69 73 20 69 73 20 74 68 65 20 6e 75 6d 62 65  his is the numbe
67d0: 72 20 6f 66 20 75 6e 75 73 65 64 20 62 79 74 65  r of unused byte
67e0: 73 20 6f 6e 0a 20 20 20 20 61 6c 6c 20 70 61 67  s on.    all pag
67f0: 65 73 20 64 69 76 69 64 65 64 20 62 79 20 74 68  es divided by th
6800: 65 20 6e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72  e number of entr
6810: 69 65 73 2e 0a 0a 4d 61 78 69 6d 75 6d 20 70 61  ies...Maximum pa
6820: 79 6c 6f 61 64 20 70 65 72 20 65 6e 74 72 79 0a  yload per entry.
6830: 0a 20 20 20 20 54 68 65 20 6c 61 72 67 65 73 74  .    The largest
6840: 20 70 61 79 6c 6f 61 64 20 73 69 7a 65 20 6f 66   payload size of
6850: 20 61 6e 79 20 65 6e 74 72 79 2e 0a 0a 45 6e 74   any entry...Ent
6860: 72 69 65 73 20 74 68 61 74 20 75 73 65 20 6f 76  ries that use ov
6870: 65 72 66 6c 6f 77 0a 0a 20 20 20 20 54 68 65 20  erflow..    The 
6880: 6e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65  number of entrie
6890: 73 20 74 68 61 74 20 75 73 65 72 20 6f 6e 65 20  s that user one 
68a0: 6f 72 20 6d 6f 72 65 20 6f 76 65 72 66 6c 6f 77  or more overflow
68b0: 20 70 61 67 65 73 2e 0a 0a 54 6f 74 61 6c 20 70   pages...Total p
68c0: 61 67 65 73 20 75 73 65 64 0a 0a 20 20 20 20 54  ages used..    T
68d0: 68 69 73 20 69 73 20 74 68 65 20 6e 75 6d 62 65  his is the numbe
68e0: 72 20 6f 66 20 70 61 67 65 73 20 75 73 65 64 20  r of pages used 
68f0: 74 6f 20 68 6f 6c 64 20 61 6c 6c 20 69 6e 66 6f  to hold all info
6900: 72 6d 61 74 69 6f 6e 20 69 6e 20 74 68 65 20 63  rmation in the c
6910: 75 72 72 65 6e 74 0a 20 20 20 20 63 61 74 65 67  urrent.    categ
6920: 6f 72 79 2e 20 20 54 68 69 73 20 69 73 20 74 68  ory.  This is th
6930: 65 20 73 75 6d 20 6f 66 20 69 6e 64 65 78 2c 20  e sum of index, 
6940: 70 72 69 6d 61 72 79 2c 20 61 6e 64 20 6f 76 65  primary, and ove
6950: 72 66 6c 6f 77 20 70 61 67 65 73 2e 0a 0a 49 6e  rflow pages...In
6960: 64 65 78 20 70 61 67 65 73 20 75 73 65 64 0a 0a  dex pages used..
6970: 20 20 20 20 54 68 69 73 20 69 73 20 74 68 65 20      This is the 
6980: 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  number of pages 
6990: 69 6e 20 61 20 74 61 62 6c 65 20 42 2d 74 72 65  in a table B-tre
69a0: 65 20 74 68 61 74 20 68 6f 6c 64 20 6f 6e 6c 79  e that hold only
69b0: 20 6b 65 79 20 28 72 6f 77 69 64 29 0a 20 20 20   key (rowid).   
69c0: 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 6e 64   information and
69d0: 20 6e 6f 20 64 61 74 61 2e 0a 0a 50 72 69 6d 61   no data...Prima
69e0: 72 79 20 70 61 67 65 73 20 75 73 65 64 0a 0a 20  ry pages used.. 
69f0: 20 20 20 54 68 69 73 20 69 73 20 74 68 65 20 6e     This is the n
6a00: 75 6d 62 65 72 20 6f 66 20 42 2d 74 72 65 65 20  umber of B-tree 
6a10: 70 61 67 65 73 20 74 68 61 74 20 68 6f 6c 64 20  pages that hold 
6a20: 62 6f 74 68 20 6b 65 79 20 61 6e 64 20 64 61 74  both key and dat
6a30: 61 2e 0a 0a 4f 76 65 72 66 6c 6f 77 20 70 61 67  a...Overflow pag
6a40: 65 73 20 75 73 65 64 0a 0a 20 20 20 20 54 68 65  es used..    The
6a50: 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66   total number of
6a60: 20 6f 76 65 72 66 6c 6f 77 20 70 61 67 65 73 20   overflow pages 
6a70: 75 73 65 64 20 66 6f 72 20 74 68 69 73 20 63 61  used for this ca
6a80: 74 65 67 6f 72 79 2e 0a 0a 55 6e 75 73 65 64 20  tegory...Unused 
6a90: 62 79 74 65 73 20 6f 6e 20 69 6e 64 65 78 20 70  bytes on index p
6aa0: 61 67 65 73 0a 0a 20 20 20 20 54 68 65 20 74 6f  ages..    The to
6ab0: 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 62 79  tal number of by
6ac0: 74 65 73 20 6f 66 20 75 6e 75 73 65 64 20 73 70  tes of unused sp
6ad0: 61 63 65 20 6f 6e 20 61 6c 6c 20 69 6e 64 65 78  ace on all index
6ae0: 20 70 61 67 65 73 2e 20 20 54 68 65 0a 20 20 20   pages.  The.   
6af0: 20 70 65 72 63 65 6e 74 61 67 65 20 61 74 20 74   percentage at t
6b00: 68 65 20 72 69 67 68 74 20 69 73 20 74 68 65 20  he right is the 
6b10: 6e 75 6d 62 65 72 20 6f 66 20 75 6e 75 73 65 64  number of unused
6b20: 20 62 79 74 65 73 20 64 69 76 69 64 65 64 20 62   bytes divided b
6b30: 79 20 74 68 65 0a 20 20 20 20 74 6f 74 61 6c 20  y the.    total 
6b40: 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  number of bytes 
6b50: 6f 6e 20 69 6e 64 65 78 20 70 61 67 65 73 2e 0a  on index pages..
6b60: 0a 55 6e 75 73 65 64 20 62 79 74 65 73 20 6f 6e  .Unused bytes on
6b70: 20 70 72 69 6d 61 72 79 20 70 61 67 65 73 0a 0a   primary pages..
6b80: 20 20 20 20 54 68 65 20 74 6f 74 61 6c 20 6e 75      The total nu
6b90: 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 6f 66  mber of bytes of
6ba0: 20 75 6e 75 73 65 64 20 73 70 61 63 65 20 6f 6e   unused space on
6bb0: 20 61 6c 6c 20 70 72 69 6d 61 72 79 20 70 61 67   all primary pag
6bc0: 65 73 2e 20 20 54 68 65 0a 20 20 20 20 70 65 72  es.  The.    per
6bd0: 63 65 6e 74 61 67 65 20 61 74 20 74 68 65 20 72  centage at the r
6be0: 69 67 68 74 20 69 73 20 74 68 65 20 6e 75 6d 62  ight is the numb
6bf0: 65 72 20 6f 66 20 75 6e 75 73 65 64 20 62 79 74  er of unused byt
6c00: 65 73 20 64 69 76 69 64 65 64 20 62 79 20 74 68  es divided by th
6c10: 65 0a 20 20 20 20 74 6f 74 61 6c 20 6e 75 6d 62  e.    total numb
6c20: 65 72 20 6f 66 20 62 79 74 65 73 20 6f 6e 20 70  er of bytes on p
6c30: 72 69 6d 61 72 79 20 70 61 67 65 73 2e 0a 0a 55  rimary pages...U
6c40: 6e 75 73 65 64 20 62 79 74 65 73 20 6f 6e 20 6f  nused bytes on o
6c50: 76 65 72 66 6c 6f 77 20 70 61 67 65 73 0a 0a 20  verflow pages.. 
6c60: 20 20 20 54 68 65 20 74 6f 74 61 6c 20 6e 75 6d     The total num
6c70: 62 65 72 20 6f 66 20 62 79 74 65 73 20 6f 66 20  ber of bytes of 
6c80: 75 6e 75 73 65 64 20 73 70 61 63 65 20 6f 6e 20  unused space on 
6c90: 61 6c 6c 20 6f 76 65 72 66 6c 6f 77 20 70 61 67  all overflow pag
6ca0: 65 73 2e 20 20 54 68 65 0a 20 20 20 20 70 65 72  es.  The.    per
6cb0: 63 65 6e 74 61 67 65 20 61 74 20 74 68 65 20 72  centage at the r
6cc0: 69 67 68 74 20 69 73 20 74 68 65 20 6e 75 6d 62  ight is the numb
6cd0: 65 72 20 6f 66 20 75 6e 75 73 65 64 20 62 79 74  er of unused byt
6ce0: 65 73 20 64 69 76 69 64 65 64 20 62 79 20 74 68  es divided by th
6cf0: 65 0a 20 20 20 20 74 6f 74 61 6c 20 6e 75 6d 62  e.    total numb
6d00: 65 72 20 6f 66 20 62 79 74 65 73 20 6f 6e 20 6f  er of bytes on o
6d10: 76 65 72 66 6c 6f 77 20 70 61 67 65 73 2e 0a 0a  verflow pages...
6d20: 55 6e 75 73 65 64 20 62 79 74 65 73 20 6f 6e 20  Unused bytes on 
6d30: 61 6c 6c 20 70 61 67 65 73 0a 0a 20 20 20 20 54  all pages..    T
6d40: 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20  he total number 
6d50: 6f 66 20 62 79 74 65 73 20 6f 66 20 75 6e 75 73  of bytes of unus
6d60: 65 64 20 73 70 61 63 65 20 6f 6e 20 61 6c 6c 20  ed space on all 
6d70: 70 72 69 6d 61 72 79 20 61 6e 64 20 6f 76 65 72  primary and over
6d80: 66 6c 6f 77 20 0a 20 20 20 20 70 61 67 65 73 2e  flow .    pages.
6d90: 20 20 54 68 65 20 70 65 72 63 65 6e 74 61 67 65    The percentage
6da0: 20 61 74 20 74 68 65 20 72 69 67 68 74 20 69 73   at the right is
6db0: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 75   the number of u
6dc0: 6e 75 73 65 64 20 62 79 74 65 73 20 0a 20 20 20  nused bytes .   
6dd0: 20 64 69 76 69 64 65 64 20 62 79 20 74 68 65 20   divided by the 
6de0: 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20  total number of 
6df0: 62 79 74 65 73 2e 0a 7d 0a 0a 23 20 4f 75 74 70  bytes..}..# Outp
6e00: 75 74 20 61 20 64 75 6d 70 20 6f 66 20 74 68 65  ut a dump of the
6e10: 20 69 6e 2d 6d 65 6d 6f 72 79 20 64 61 74 61 62   in-memory datab
6e20: 61 73 65 2e 20 54 68 69 73 20 63 61 6e 20 62 65  ase. This can be
6e30: 20 75 73 65 64 20 66 6f 72 20 6d 6f 72 65 0a 23   used for more.#
6e40: 20 63 6f 6d 70 6c 65 78 20 6f 66 66 6c 69 6e 65   complex offline
6e50: 20 61 6e 61 6c 79 73 69 73 2e 0a 23 0a 70 75 74   analysis..#.put
6e60: 73 20 22 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  s "*************
6e70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
6e80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
6e90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
6ea0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 22 0a 70 75 74 73 20  *********".puts 
6eb0: 22 54 68 65 20 65 6e 74 69 72 65 20 74 65 78 74  "The entire text
6ec0: 20 6f 66 20 74 68 69 73 20 72 65 70 6f 72 74 20   of this report 
6ed0: 63 61 6e 20 62 65 20 73 6f 75 72 63 65 64 20 69  can be sourced i
6ee0: 6e 74 6f 20 61 6e 79 20 53 51 4c 20 64 61 74 61  nto any SQL data
6ef0: 62 61 73 65 22 0a 70 75 74 73 20 22 65 6e 67 69  base".puts "engi
6f00: 6e 65 20 66 6f 72 20 66 75 72 74 68 65 72 20 61  ne for further a
6f10: 6e 61 6c 79 73 69 73 2e 20 20 41 6c 6c 20 6f 66  nalysis.  All of
6f20: 20 74 68 65 20 74 65 78 74 20 61 62 6f 76 65 20   the text above 
6f30: 69 73 20 61 6e 20 53 51 4c 20 63 6f 6d 6d 65 6e  is an SQL commen
6f40: 74 2e 22 0a 70 75 74 73 20 22 54 68 65 20 64 61  t.".puts "The da
6f50: 74 61 20 75 73 65 64 20 74 6f 20 67 65 6e 65 72  ta used to gener
6f60: 61 74 65 20 74 68 69 73 20 72 65 70 6f 72 74 20  ate this report 
6f70: 66 6f 6c 6c 6f 77 73 3a 22 0a 70 75 74 73 20 22  follows:".puts "
6f80: 2a 2f 22 0a 70 75 74 73 20 22 42 45 47 49 4e 3b  */".puts "BEGIN;
6f90: 22 0a 70 75 74 73 20 24 74 61 62 6c 65 64 65 66  ".puts $tabledef
6fa0: 0a 75 6e 73 65 74 20 2d 6e 6f 63 6f 6d 70 6c 61  .unset -nocompla
6fb0: 69 6e 20 78 0a 6d 65 6d 20 65 76 61 6c 20 7b 53  in x.mem eval {S
6fc0: 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 73 70 61  ELECT * FROM spa
6fd0: 63 65 5f 75 73 65 64 7d 20 78 20 7b 0a 20 20 70  ce_used} x {.  p
6fe0: 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 22  uts -nonewline "
6ff0: 49 4e 53 45 52 54 20 49 4e 54 4f 20 73 70 61 63  INSERT INTO spac
7000: 65 5f 75 73 65 64 20 56 41 4c 55 45 53 22 0a 20  e_used VALUES". 
7010: 20 73 65 74 20 73 65 70 20 28 0a 20 20 66 6f 72   set sep (.  for
7020: 65 61 63 68 20 63 6f 6c 20 24 78 28 2a 29 20 7b  each col $x(*) {
7030: 0a 20 20 20 20 73 65 74 20 76 20 24 78 28 24 63  .    set v $x($c
7040: 6f 6c 29 0a 20 20 20 20 69 66 20 7b 24 76 3d 3d  ol).    if {$v==
7050: 22 22 20 7c 7c 20 21 5b 73 74 72 69 6e 67 20 69  "" || ![string i
7060: 73 20 64 6f 75 62 6c 65 20 24 76 5d 7d 20 7b 73  s double $v]} {s
7070: 65 74 20 76 20 5b 71 75 6f 74 65 20 24 76 5d 7d  et v [quote $v]}
7080: 0a 20 20 20 20 70 75 74 73 20 2d 6e 6f 6e 65 77  .    puts -nonew
7090: 6c 69 6e 65 20 24 73 65 70 24 76 0a 20 20 20 20  line $sep$v.    
70a0: 73 65 74 20 73 65 70 20 2c 0a 20 20 7d 0a 20 20  set sep ,.  }.  
70b0: 70 75 74 73 20 22 29 3b 22 0a 7d 0a 70 75 74 73  puts ");".}.puts
70c0: 20 22 43 4f 4d 4d 49 54 3b 22 0a 0a 7d 20 65 72   "COMMIT;"..} er
70d0: 72 5d 7d 20 7b 0a 20 20 70 75 74 73 20 22 45 52  r]} {.  puts "ER
70e0: 52 4f 52 3a 20 24 65 72 72 22 0a 20 20 70 75 74  ROR: $err".  put
70f0: 73 20 24 65 72 72 6f 72 49 6e 66 6f 0a 20 20 65  s $errorInfo.  e
7100: 78 69 74 20 31 0a 7d 0a                          xit 1.}.