如何在SQLite数据库中找到单个表的磁盘使用情况而不将其复制到新的空数据库中?
答案 0 :(得分:78)
您可以使用http://www.sqlite.org/download.html中的sqlite3_analyzer。
这是一个非常酷的工具。它显示了每个表使用和不使用索引时使用的页数(默认情况下,每个页面为1024字节)。
这是Northwind数据库的示例sqlite3_analyzer输出:
*** 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语句,这些语句可用于创建具有使用情况统计信息的数据库,然后您可以对其进行分析。
答案 1 :(得分:4)
我意识到这个答案完全违反了问题的精神,但是如果没有复制文件,它确实可以帮助你实现......
$ 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
答案 2 :(得分:3)
可以从dbstat表中获取每个表或索引使用的所有页面的详细信息,也可以将其汇总以获取每个表或索引的磁盘使用情况。
例如,可以使用更多磁盘空间来获得10个表,如下所示:
sqlite> select name, sum(pgsize) as size from dbstat group by name order by size desc limit 10;
答案 3 :(得分:2)
如果您使用的是Linux或OSX,或者以其他方式使用unix实用程序awk(以及可选的sort),则可以执行以下操作以通过转储分析获取计数和估计的大小:
# substitute '.dump' for '.dump mytable' if you want to limit to specific table
sqlite3 db.sqlite3 '.dump' | awk -f sqlite3_size.awk | sort -k3 -n -r
返回:
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, name, "\""); # extract "xxx" from INSERT INTO "xxx"
split($0, values, "VALUES"); # extract everything after VALUES
gsub(/[\047,]/, "", values[2]); # remove single-quotes and commas
sizes[name[2]] += length(values[2]) - 3; # subtract 3 for parens and semicolon
counts[name[2]] += 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";
}
}
估计的大小基于“ INSERT INTO”命令的字符串长度,因此不会等于磁盘上的实际大小,但是对我来说,计数加估计的大小比其他替代方法(例如:页数。
答案 4 :(得分:0)
我在这里遇到其他答案的问题(即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