FirefoxのSQLiteDBの再編成について(すこし詳細に)
物凄い人気ですね。
これについてちょっと詳しく書いてみようと思う。
DBファイルの断片化
WindowsのファイルシステムをデフラグしましょってやつはDBファイルにも言えることだ。
仕組みをLeo's Chronicle: データベースシステム入門:「データベースは体育会系図書館?」に習って「図書館」に例えてみる。
- 図書館
- DBファイル
- 本
- 中身のデータ一行
といえるだろう。
単純にデータが追加されていくだけなら、本を本棚の末尾に追加するだけなのでデータは詰まったままだし楽チンだ*1。
途中データの削除(本を抜き取る)を考えてみる。抜き取った後本を詰めないと空白ができる。
また、データ更新(本の交換)を考えてみる。同じ大きさなら良いが。大きかったり、小さかったりすると空白ができる。
こうしてデータ削除/更新を頻繁に行うと穴だらけの本棚になる。これが断片化だ。ファイルシステムのそれも同じ概念だろう。
毎回本を詰めれば良いじゃないかと思うかもしれないが、後続の本を一つずつ詰めるのは大変労力かかるので、この問題は後回しにするのが近作のRDBMSだ。
断片化が進むとどうなるかというと、本棚を一望した時に見つける本の量((SQLiteではページ・サイズといい、PRAGMA page_size
で見ることが可能))が減る。本の冊数の割りに全部を見るのに時間がかかることになる。これがパフォーマンスの悪化要因の一つだ。
索引
どうしても書店のように本棚を縦横に綺麗に並べたくなってしまいますが、そこはさすが1970年代の研究者。発想が違います。彼らは本棚を縦横ではなく、ピラミッド状に並べることを考えました。
Leo's Chronicle: データベースシステム入門:「データベースは体育会系図書館?」
の様に、図書館で例えると索引の説明が難しくなってしまうのだが...。
索引もデータの増減により最初は綺麗だった「ピラミッド構造」がだんだん歪になっていき、使い難いものになる。
これを検索しやすい形に整形するのがREINDEXコマンドとなる。
議事録をマインドマップを手で書いて、あとでソフトを使って綺麗にする、みたいなものだ。
まえおき、終わり
Firefoxが使用するDBファイル
Firefoxでは主に以下のファイルがSQLiteDBだ。
ファイル名 | データサイズ | 更新度 | 概要 |
---|---|---|---|
urlclassifier3.sqlite | 大 | 高 | 悪意のあるサイトや偽装サイトのデータ |
places.sqlite | 大 | 高 | ブックマークや訪問履歴 |
formhistory.sqlite | 中 | 中 | フォームの入力履歴 |
signons.sqlite | 小 | 小 | パスワードの保存許可設定やパスワード自体 |
cookies.sqlite | 中 | 中 | Cookieデータ |
content-prefs.sqlite | 中 | 低 | サイト毎の設定 |
downloads.sqlite | 小 | 小 | ダウンロード履歴 |
permissions.sqlite | 小 | 小 | Cookieや画像読み込みなどの許可設定 |
search.sqlite | 小 | 小 | 検索エンジン |
※データサイズ、更新度は個人的な感覚でつけているので個人差があると思う
urlclassifier3.sqlite
とにかくサイズが大きい(通常のRDBMSのDBファイルに比べたら小さいものだが)
さらに、このファイルはプロファイルフォルダに無く、別のフォルダに保管されている。
- Windows
- %USERPROFILE%\Local Setteings\Application Data\Mozilla\Firefox\Profies\ランダム文字列.プロファイル名\ 以下
- Mac
- ~/Library/Caches/Firefox/Profiles/ランダム文字列.プロファイル名/ 以下(elimさん、ありがとうございます)
- Linux
- ~/.mozilla/firefox/ランダム文字列.プロファイル名/ 以下(necydaさん、ありがとうございます)
VACUUM,REINDEXの第一候補である。これを再編成することで起動時のパフォーマンスはかなり上がるはず。
places.sqlite
ブックマーク、訪問履歴を扱っているので更新頻度が高く、履歴の保存日数設定によってはサイズも大きくなる。
再編成第二候補。
再編成することで、ロケーションバーでの補完のパフォーマンスが改善されると思われる。
断片化が進んでいるかの調査方法
sqlite3コマンドが使えるという前提で書く。
以下のコマンドで各値を得る。
- ページサイズ(Byte)
PRAGMA page_size
- 全体ページ数
PRAGMA page_count
- 空きページ数
PRAGMA freelist_count
ページサイズ * 全体ページ数 ≒ ファイルサイズ である。また断片化が進んでいるほど、空きページ数が大きくなる。
urlclassifier3.sqliteを例にとると
- ページサイズ
- 4096
- 全体ページ数
- 6080
- 空きページ数
- 567
約10%、2.2MBほどの空きがあることが分かる。
この空きページ数が再編成の一つの指標になると思う。どのくらい断片化すると体感速度に影響が出るのか分からないけど...。
最後に、Webサイトの読み速度などに変化はないはずなので何でも早くなるわけじゃないことに注意。
*1:本棚は自動拡張/縮小とする