| Index: third_party/sqlite/sqlite-src-3100200/tool/spaceanal.tcl
|
| diff --git a/third_party/sqlite/sqlite-src-3080704/tool/spaceanal.tcl b/third_party/sqlite/sqlite-src-3100200/tool/spaceanal.tcl
|
| similarity index 93%
|
| copy from third_party/sqlite/sqlite-src-3080704/tool/spaceanal.tcl
|
| copy to third_party/sqlite/sqlite-src-3100200/tool/spaceanal.tcl
|
| index a227b8524359c00b9e75f052c092d5e65ab0575f..38d954162e438f86b9505dd602ad478e41549a4b 100644
|
| --- a/third_party/sqlite/sqlite-src-3080704/tool/spaceanal.tcl
|
| +++ b/third_party/sqlite/sqlite-src-3100200/tool/spaceanal.tcl
|
| @@ -4,11 +4,41 @@
|
| #
|
|
|
| if {[catch {
|
| +
|
| +# Argument $tname is the name of a table within the database opened by
|
| +# database handle [db]. Return true if it is a WITHOUT ROWID table, or
|
| +# false otherwise.
|
| +#
|
| +proc is_without_rowid {tname} {
|
| + set t [string map {' ''} $tname]
|
| + db eval "PRAGMA index_list = '$t'" o {
|
| + if {$o(origin) == "pk"} {
|
| + set n $o(name)
|
| + if {0==[db one { SELECT count(*) FROM sqlite_master WHERE name=$n }]} {
|
| + return 1
|
| + }
|
| + }
|
| + }
|
| + return 0
|
| +}
|
| +
|
| # Get the name of the database to analyze
|
| #
|
| proc usage {} {
|
| set argv0 [file rootname [file tail [info nameofexecutable]]]
|
| - puts stderr "Usage: $argv0 database-name"
|
| + puts stderr "Usage: $argv0 ?--pageinfo? ?--stats? database-filename"
|
| + puts stderr {
|
| +Analyze the SQLite3 database file specified by the "database-filename"
|
| +argument and output a report detailing size and storage efficiency
|
| +information for the database and its constituent tables and indexes.
|
| +
|
| +Options:
|
| +
|
| + --stats Output SQL text that creates a new database containing
|
| + statistics about the database that was analyzed
|
| +
|
| + --pageinfo Show how each page of the database-file is used
|
| +}
|
| exit 1
|
| }
|
| set file_to_analyze {}
|
| @@ -70,7 +100,6 @@ if {[catch {sqlite3 db $file_to_analyze -uri 1} msg]} {
|
| puts stderr "error trying to open $file_to_analyze: $msg"
|
| exit 1
|
| }
|
| -register_dbstat_vtab db
|
|
|
| db eval {SELECT count(*) FROM sqlite_master}
|
| set pageSize [expr {wide([db one {PRAGMA page_size}])}]
|
| @@ -125,6 +154,7 @@ set tabledef {CREATE TABLE space_used(
|
| is_index boolean, -- TRUE if it is an index, false for a table
|
| nentry int, -- Number of entries in the BTree
|
| leaf_entries int, -- Number of leaf entries
|
| + depth int, -- Depth of the b-tree
|
| payload int, -- Total amount of data stored in this table or index
|
| ovfl_payload int, -- Total amount of data stored on overflow pages
|
| ovfl_cnt int, -- Number of entries that use overflow
|
| @@ -147,41 +177,31 @@ db eval {CREATE TEMP TABLE dbstat AS SELECT * FROM temp.stat
|
| ORDER BY name, path}
|
| db eval {DROP TABLE temp.stat}
|
|
|
| -proc isleaf {pagetype is_index} {
|
| - return [expr {$pagetype == "leaf" || ($pagetype == "internal" && $is_index)}]
|
| -}
|
| -proc isoverflow {pagetype is_index} {
|
| - return [expr {$pagetype == "overflow"}]
|
| -}
|
| -proc isinternal {pagetype is_index} {
|
| - return [expr {$pagetype == "internal" && $is_index==0}]
|
| -}
|
| -
|
| -db func isleaf isleaf
|
| -db func isinternal isinternal
|
| -db func isoverflow isoverflow
|
| -
|
| set isCompressed 0
|
| set compressOverhead 0
|
| +set depth 0
|
| set sql { SELECT name, tbl_name FROM sqlite_master WHERE rootpage>0 }
|
| foreach {name tblname} [concat sqlite_master sqlite_master [db eval $sql]] {
|
|
|
| set is_index [expr {$name!=$tblname}]
|
| + set idx_btree [expr {$is_index || [is_without_rowid $name]}]
|
| db eval {
|
| SELECT
|
| sum(ncell) AS nentry,
|
| - sum(isleaf(pagetype, $is_index) * ncell) AS leaf_entries,
|
| + sum((pagetype=='leaf')*ncell) AS leaf_entries,
|
| sum(payload) AS payload,
|
| - sum(isoverflow(pagetype, $is_index) * payload) AS ovfl_payload,
|
| + sum((pagetype=='overflow') * payload) AS ovfl_payload,
|
| sum(path LIKE '%+000000') AS ovfl_cnt,
|
| max(mx_payload) AS mx_payload,
|
| - sum(isinternal(pagetype, $is_index)) AS int_pages,
|
| - sum(isleaf(pagetype, $is_index)) AS leaf_pages,
|
| - sum(isoverflow(pagetype, $is_index)) AS ovfl_pages,
|
| - sum(isinternal(pagetype, $is_index) * unused) AS int_unused,
|
| - sum(isleaf(pagetype, $is_index) * unused) AS leaf_unused,
|
| - sum(isoverflow(pagetype, $is_index) * unused) AS ovfl_unused,
|
| - sum(pgsize) AS compressed_size
|
| + sum(pagetype=='internal') AS int_pages,
|
| + sum(pagetype=='leaf') AS leaf_pages,
|
| + sum(pagetype=='overflow') AS ovfl_pages,
|
| + sum((pagetype=='internal') * unused) AS int_unused,
|
| + sum((pagetype=='leaf') * unused) AS leaf_unused,
|
| + sum((pagetype=='overflow') * unused) AS ovfl_unused,
|
| + sum(pgsize) AS compressed_size,
|
| + max((length(CASE WHEN path LIKE '%+%' THEN '' ELSE path END)+3)/4)
|
| + AS depth
|
| FROM temp.dbstat WHERE name = $name
|
| } break
|
|
|
| @@ -217,6 +237,7 @@ foreach {name tblname} [concat sqlite_master sqlite_master [db eval $sql]] {
|
| $is_index,
|
| $nentry,
|
| $leaf_entries,
|
| + $depth,
|
| $payload,
|
| $ovfl_payload,
|
| $ovfl_cnt,
|
| @@ -326,7 +347,9 @@ proc subreport {title where showFrag} {
|
| int(sum(int_unused)) AS int_unused,
|
| int(sum(ovfl_unused)) AS ovfl_unused,
|
| int(sum(gap_cnt)) AS gap_cnt,
|
| - int(sum(compressed_size)) AS compressed_size
|
| + int(sum(compressed_size)) AS compressed_size,
|
| + int(max(depth)) AS depth,
|
| + count(*) AS cnt
|
| FROM space_used WHERE $where" {} {}
|
|
|
| # Output the sub-report title, nicely decorated with * characters.
|
| @@ -363,7 +386,7 @@ proc subreport {title where showFrag} {
|
| "]
|
| set avg_fanout [mem eval "
|
| SELECT (sum(leaf_pages+int_pages)-$nTab)/sum(int_pages) FROM space_used
|
| - WHERE $where AND is_index = 0
|
| + WHERE $where
|
| "]
|
| set avg_fanout [format %.2f $avg_fanout]
|
| }
|
| @@ -381,6 +404,7 @@ proc subreport {title where showFrag} {
|
| statline {Bytes used after compression} $compressed_size $pct
|
| }
|
| statline {Bytes of payload} $payload $payload_percent
|
| + if {$cnt==1} {statline {B-tree depth} $depth}
|
| statline {Average payload per entry} $avg_payload
|
| statline {Average unused bytes per entry} $avg_unused
|
| if {[info exists avg_fanout]} {
|
|
|