SQLite表磁盘使用情况

SQLite表磁盘使用情况,sqlite,Sqlite,如何在不将单个表复制到新的空数据库中的情况下找出SQLite数据库中单个表的磁盘使用情况?您可以从中使用 这是一个非常酷的工具。它显示有索引和无索引的每个表使用的页数(默认情况下,每个页为1024字节) 这是Northwind数据库的sqlite3_分析器输出示例: *** Page counts for all tables with their indices ******************** EMPLOYEES............................. 200

如何在不将单个表复制到新的空数据库中的情况下找出SQLite数据库中单个表的磁盘使用情况?

您可以从中使用

这是一个非常酷的工具。它显示有索引和无索引的每个表使用的页数(默认情况下,每个页为1024字节)

这是Northwind数据库的sqlite3_分析器输出示例:

*** Page counts for all tables with their indices ********************

EMPLOYEES............................. 200         34.4% 
ORDERS................................ 152         26.2% 
CATEGORIES............................ 90          15.5% 
ORDER DETAILS......................... 81          13.9% 
CUSTOMERS............................. 17           2.9% 
SQLITE_MASTER......................... 11           1.9% 
PRODUCTS.............................. 7            1.2% 
SUPPLIERS............................. 7            1.2% 
TERRITORIES........................... 6            1.0% 
CUSTOMERCUSTOMERDEMO.................. 2            0.34% 
CUSTOMERDEMOGRAPHICS.................. 2            0.34% 
EMPLOYEETERRITORIES................... 2            0.34% 
REGION................................ 2            0.34% 
SHIPPERS.............................. 2            0.34% 

它还生成SQL语句,可用于创建包含使用情况统计信息的数据库,然后进行分析

我意识到这个答案完全违背了问题的精神,但它确实可以在不复制文件的情况下获得大小

$ ls -lh db.sqlite
-rw-r--r-- 1 dude bros 44M Jan 11 18:44 db.sqlite
$ sqlite3 db.sqlite
sqlite> drop table my_table;
sqlite> vacuum;
sqlite> ^D
$ ls -lh db.sqlite
-rw-r--r-- 1 dude bros 23M Jan 11 18:44 db.sqlite

如果您使用的是linux或OSX,或者unix实用程序awk(以及可选的排序)可用,则可以通过转储分析执行以下操作以获取计数和估计大小:

# substitute '.dump' for '.dump mytable' if you want to limit to specific table
sqlite3 db.sqlite3 '.dump' | awk -f sqlite3_size.awk
返回:

table            count   est. size
my_biggest_table 1090    60733958
my_table2        26919   7796902
my_table3        10390   2732068
并使用awk脚本:

/INSERT INTO/ {                              # parse INSERT commands
    split($0, values, "VALUES");             # extract everything after VALUES
    split(values[1], name, "INSERT INTO");   # get tablename
    tablename = name[2];                     #
    gsub(/[\047\042]/, "", tablename);         # remove single and double quotes from name
    gsub(/[\047,]/, "", values[2]);          # remove single-quotes and commas
    sizes[tablename] += length(values[2]) - 3; # subtract 3 for parens and semicolon
    counts[tablename] += 1;
}

END {
    print "table\tcount\test. size"
    for(k in sizes) {
        # print and sort in descending order:
        print k "\t" counts[k] "\t" sizes[k] | "sort -k3 -n -r";

        # or, if you don't have the sort command:
        print k "\t" counts[k] "\t" sizes[k];
    }
}

估计的大小基于“INSERT-INTO”命令的字符串长度,因此不会等于磁盘上的实际大小,但对我来说,count加上估计的大小比其他选项(如页面计数)更有用。

我在这里遇到了其他答案的问题(即sqlite_analyzer不在Linux上工作)。'最后创建了下面的Bash函数(临时)将每个表写到磁盘上,作为评估磁盘大小的一种方法。从技术上讲,这是复制数据库,这不符合OP问题的精神,但它提供了我想要的信息

function sqlite_size() {
  TMPFILE="/tmp/__sqlite_size_tmp"
  DB=$1
  IFS=" " TABLES=`sqlite3 $DB .tables`
  for i in $TABLES; do
    \rm -f "$TMPFILE"
    sqlite3 $DB ".dump $i" | sqlite3 $TMPFILE
    echo $i `cat $TMPFILE | wc -c`
    \rm -f "$TMPFILE"
  done
}
例如:

$ sqlite_size sidekick.sqlite
SequelizeMeta 12288
events 16384
histograms 20480
programs 20480


可以从dbstat表中获取每个表或索引使用的所有页面的详细信息,也可以将这些信息聚合起来,以获取每个表或索引的磁盘使用情况

例如,可以使用更多磁盘空间获取10个表,如下所示:

sqlite> select name, sum(pgsize) as size from dbstat group by name order by size desc limit 10;

基于

注意,sqlite3_analyze需要很长时间才能运行。它在linux上是如何工作的?我解压缩了它,但我无法启动它是的,64位Linux版本似乎丢失了。奇怪。只适用于现代sqlite实现,因为它依赖于
dbstat
表,该表可能并不总是在SQLite3中。您确定它没有复制下面的文件吗?真空需要与数据库大小一样多的磁盘空间,至少,我认为(我不太确定这一点,但我记得读过的一些东西,以及我对几乎满分区的实验,让我相信是这样的。)此外,通过真空恢复的空间可能已经从其他表中回收,所以你可能需要抽真空;测试文件大小;升降台;真空;测试文件大小要获得更好的输出,请使用:
sqlite_size/var/lib/grafana/grafana.db | sort-k2-n | column-t
(它是用漂亮的列排序的)仅当sqlite在编译时启用了
sqlite_ENABLE_DBSTAT_VTAB
。幸运的是,对于Ubuntu 19.10等软件包来说,情况就是这样。