Использование дискового пространства SQLite

Как я могу узнать об использовании диска в одной таблице внутри базы данных SQLite, не копируя ее в новой пустой базе данных?

Ответ 1

Вы можете использовать sqlite3_analyzer из https://www.sqlite.org/download.html.

Это действительно крутой инструмент. Он показывает количество страниц, используемых каждой таблицей с индексами и без них (каждая страница по умолчанию составляет 1024 байта).

Это пример вывода sqlite3_analyzer для базы данных Northwind:

*** 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, которые можно использовать для создания базы данных со статистикой использования, которую затем можно проанализировать.

Ответ 2

Я понимаю, что этот ответ полностью нарушает дух вопроса, но он дает вам размер без копирования файла...

$ 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

Ответ 3

Если вы используете 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

который возвращает:

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", и поэтому не будет равен фактическому размеру на диске, но для меня число плюс предполагаемый размер более полезен, чем другие альтернативы, такие как количество страниц.

Ответ 4

Я столкнулся с проблемами с другими ответами здесь (а именно sqlite_analyzer не работает на Linux). 'Закончилось создание следующей функции Bash для (временной) записи каждой таблицы на диск для оценки размера на диске. Технически это копирование БД, что не соответствует духу вопроса ОП, но оно дало мне информацию, за которой я следовал.

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