OLD | NEW |
(Empty) | |
| 1 # Run this TCL script using "testfixture" in order get a report that shows |
| 2 # how much disk space is used by a particular data to actually store data |
| 3 # versus how much space is unused. |
| 4 # |
| 5 |
| 6 # Get the name of the database to analyze |
| 7 # |
| 8 if {[llength $argv]!=1} { |
| 9 puts stderr "Usage: $argv0 database-name" |
| 10 exit 1 |
| 11 } |
| 12 set file_to_analyze [lindex $argv 0] |
| 13 |
| 14 # Open the database |
| 15 # |
| 16 sqlite db [lindex $argv 0] |
| 17 set DB [btree_open [lindex $argv 0]] |
| 18 |
| 19 # Output the schema for the generated report |
| 20 # |
| 21 puts \ |
| 22 {BEGIN; |
| 23 CREATE TABLE space_used( |
| 24 name clob, -- Name of a table or index in the database file |
| 25 is_index boolean, -- TRUE if it is an index, false for a table |
| 26 payload int, -- Total amount of data stored in this table or index |
| 27 pri_pages int, -- Number of primary pages used |
| 28 ovfl_pages int, -- Number of overflow pages used |
| 29 pri_unused int, -- Number of unused bytes on primary pages |
| 30 ovfl_unused int -- Number of unused bytes on overflow pages |
| 31 );} |
| 32 |
| 33 # This query will be used to find the root page number for every index and |
| 34 # table in the database. |
| 35 # |
| 36 set sql { |
| 37 SELECT name, type, rootpage FROM sqlite_master |
| 38 UNION ALL |
| 39 SELECT 'sqlite_master', 'table', 2 |
| 40 ORDER BY 1 |
| 41 } |
| 42 |
| 43 # Initialize variables used for summary statistics. |
| 44 # |
| 45 set total_size 0 |
| 46 set total_primary 0 |
| 47 set total_overflow 0 |
| 48 set total_unused_primary 0 |
| 49 set total_unused_ovfl 0 |
| 50 |
| 51 # Analyze every table in the database, one at a time. |
| 52 # |
| 53 foreach {name type rootpage} [db eval $sql] { |
| 54 set cursor [btree_cursor $DB $rootpage 0] |
| 55 set go [btree_first $cursor] |
| 56 set size 0 |
| 57 catch {unset pg_used} |
| 58 set unused_ovfl 0 |
| 59 set n_overflow 0 |
| 60 while {$go==0} { |
| 61 set payload [btree_payload_size $cursor] |
| 62 incr size $payload |
| 63 set stat [btree_cursor_dump $cursor] |
| 64 set pgno [lindex $stat 0] |
| 65 set freebytes [lindex $stat 4] |
| 66 set pg_used($pgno) $freebytes |
| 67 if {$payload>238} { |
| 68 set n [expr {($payload-238+1019)/1020}] |
| 69 incr n_overflow $n |
| 70 incr unused_ovfl [expr {$n*1020+238-$payload}] |
| 71 } |
| 72 set go [btree_next $cursor] |
| 73 } |
| 74 btree_close_cursor $cursor |
| 75 set n_primary [llength [array names pg_used]] |
| 76 set unused_primary 0 |
| 77 foreach x [array names pg_used] {incr unused_primary $pg_used($x)} |
| 78 regsub -all ' $name '' name |
| 79 puts -nonewline "INSERT INTO space_used VALUES('$name'" |
| 80 puts -nonewline ",[expr {$type=="index"}]" |
| 81 puts ",$size,$n_primary,$n_overflow,$unused_primary,$unused_ovfl);" |
| 82 incr total_size $size |
| 83 incr total_primary $n_primary |
| 84 incr total_overflow $n_overflow |
| 85 incr total_unused_primary $unused_primary |
| 86 incr total_unused_ovfl $unused_ovfl |
| 87 } |
| 88 |
| 89 # Output summary statistics: |
| 90 # |
| 91 puts "-- Total payload size: $total_size" |
| 92 puts "-- Total pages used: $total_primary primary and $total_overflow overflow" |
| 93 set file_pgcnt [expr {[file size [lindex $argv 0]]/1024}] |
| 94 puts -nonewline "-- Total unused bytes on primary pages: $total_unused_primary" |
| 95 if {$total_primary>0} { |
| 96 set upp [expr {$total_unused_primary/$total_primary}] |
| 97 puts " (avg $upp bytes/page)" |
| 98 } else { |
| 99 puts "" |
| 100 } |
| 101 puts -nonewline "-- Total unused bytes on overflow pages: $total_unused_ovfl" |
| 102 if {$total_overflow>0} { |
| 103 set upp [expr {$total_unused_ovfl/$total_overflow}] |
| 104 puts " (avg $upp bytes/page)" |
| 105 } else { |
| 106 puts "" |
| 107 } |
| 108 set n_free [expr {$file_pgcnt-$total_primary-$total_overflow}] |
| 109 if {$n_free>0} {incr n_free -1} |
| 110 puts "-- Total pages on freelist: $n_free" |
| 111 puts "COMMIT;" |
OLD | NEW |