SQLite | データベース | 空き領域の整理 (VACUUM)

SQLite データベースでデータの追加や削除を繰り返していると、保存されているデータ量に比べてファイルサイズが大きくなることがあります。ここでは、VACUUM 文を使用して未使用領域を回収する方法について説明します。

VACUUM の使用

SQLite データベースを作成すると1つのファイルが作成され、テーブルや保存されたデータはそのファイルに保存されます。テーブルにデータを追加していくとデータベースファイルのサイズも少しずつ大きくなりますが、テーブルからデータを削除しても、データベースファイルのサイズはすぐには小さくなりません。ファイル内で使用されていた領域はすぐに削除されるのではなく、次にデータが追加されたときに再利用するために残されるためです。

通常は気にする必要はありませんが、ファイルサイズが気になる場合は、VACUUM 文を実行して未使用領域を回収し、ファイルサイズを小さくできます。

VACUUM 文は次のように実行します。

VACUUM;

VACUUM 文を実行すると、データベースの内容を一度一時データベースへ移し、その後で戻す処理が行われます。これにより空き領域をなくし、データを順番に保存し直して整理します。

注意点として、VACUUM の対象になるのは main データベースだけです。接続されたデータベースは VACUUM の対象になりません。また、INTEGER PRIMARY KEY が設定されたカラムがないテーブルの場合、保存されているデータに割り当てられた ROWID は変更されることがあります。

実習

それでは実習してみます。次のように、データベースのファイルサイズが 16,384 バイトの sample.sqlite3 ファイルがあります。

$ ls -al
total 5048
drwxr-xr-x@ 7 kimkc  staff      238 10 19 23:20 .
drwxr-xr-x  9 kimkc  staff      306 10 17 23:49 ..
drwxr-xr-x  6 kimkc  staff      204 10 19 23:20 bak
-rw-r--r--  1 kimkc  staff    16384 10 19 23:20 sample.sqlite3
-rwxr-xr-x@ 1 kimkc  staff   691768 10 11 18:31 sqldiff
-rwxr-xr-x@ 1 kimkc  staff  1152260 10 11 18:32 sqlite3
-rwxr-xr-x@ 1 kimkc  staff   719796 10 11 18:31 sqlite3_analyzer

データベースに接続し、データベース内にあるテーブルを1つ削除します。

$ sqlite3 sample.sqlite3 
SQLite version 3.19.3 2017-06-27 16:48:08
Enter ".help" for usage hints.
sqlite> .tables
select    user      username
sqlite> drop table user;
sqlite> 

テーブルを削除してからデータベースのファイルサイズを確認すると、削除前と変わらず 16,384 バイトのままです。

$ ls -al
total 5048
drwxr-xr-x@ 7 kimkc  staff      238 10 19 23:24 .
drwxr-xr-x  9 kimkc  staff      306 10 17 23:49 ..
drwxr-xr-x  6 kimkc  staff      204 10 19 23:20 bak
-rw-r--r--  1 kimkc  staff    16384 10 19 23:24 sample.sqlite3
-rwxr-xr-x@ 1 kimkc  staff   691768 10 11 18:31 sqldiff
-rwxr-xr-x@ 1 kimkc  staff  1152260 10 11 18:32 sqlite3
-rwxr-xr-x@ 1 kimkc  staff   719796 10 11 18:31 sqlite3_analyzer

このように、テーブルやデータを削除しても、すぐにデータベースのファイルサイズが小さくなるわけではありません。それでは、データベースに再度接続して VACUUM 文を実行してみましょう。

$ sqlite3 sample.sqlite3 
SQLite version 3.19.3 2017-06-27 16:48:08
Enter ".help" for usage hints.
sqlite> vacuum;
sqlite> 

VACUUM 文を実行した後にデータベースのファイルサイズを確認すると、12,288 バイトに小さくなっていることが分かります。

$ ls -al
total 5040
drwxr-xr-x@ 7 kimkc  staff      238 10 19 23:29 .
drwxr-xr-x  9 kimkc  staff      306 10 17 23:49 ..
drwxr-xr-x  6 kimkc  staff      204 10 19 23:20 bak
-rw-r--r--  1 kimkc  staff    12288 10 19 23:29 sample.sqlite3
-rwxr-xr-x@ 1 kimkc  staff   691768 10 11 18:31 sqldiff
-rwxr-xr-x@ 1 kimkc  staff  1152260 10 11 18:32 sqlite3
-rwxr-xr-x@ 1 kimkc  staff   719796 10 11 18:31 sqlite3_analyzer
kimkcui-MacBook-Pro:sqlite-tools-osx-x86-3300100 kimkc$ 

このように VACUUM を実行すると、未使用領域を回収してファイルサイズを小さくできます。ファイルサイズが気になる場合は VACUUM を実行しましょう。