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