Hatena::ブログ(Diary)

hogehoge @teramako RSSフィード

 | 

2009-05-12

FirefoxのSQLiteDBの再編成について(すこし詳細に)

物凄い人気ですね。

これについてちょっと詳しく書いてみようと思う。

DBファイルの断片化

WindowsファイルシステムデフラグしましょってやつはDBファイルにも言えることだ。

仕組みをLeo’s Chronicle: データベースシステム入門:「データベースは体育会系図書館?」に習って「図書館」に例えてみる。

図書館
DBファイル
中身のデータ一行

といえるだろう。

単純にデータが追加されていくだけなら、本を本棚の末尾に追加するだけなのでデータは詰まったままだし楽チンだ*1

途中データの削除(本を抜き取る)を考えてみる。抜き取った後本を詰めないと空白ができる。

また、データ更新(本の交換)を考えてみる。同じ大きさなら良いが。大きかったり、小さかったりすると空白ができる。

こうしてデータ削除/更新を頻繁に行うと穴だらけの本棚になる。これが断片化だ。ファイルシステムのそれも同じ概念だろう。

毎回本を詰めれば良いじゃないかと思うかもしれないが、後続の本を一つずつ詰めるのは大変労力かかるので、この問題は後回しにするのが近作のRDBMSだ。

断片化が進むとどうなるかというと、本棚を一望した時に見つける本の量*2が減る。本の冊数の割りに全部を見るのに時間がかかることになる。これがパフォーマンスの悪化要因の一つだ。

索引

どうしても書店のように本棚を縦横に綺麗に並べたくなってしまいますが、そこはさすが1970年代の研究者。発想が違います。彼らは本棚を縦横ではなく、ピラミッド状に並べることを考えました。

Leo%27s Chronicle: データベースシステム入門:「データベースは体育会系図書館?」

の様に、図書館で例えると索引の説明が難しくなってしまうのだが...。

索引もデータの増減により最初は綺麗だった「ピラミッド構造」がだんだん歪になっていき、使い難いものになる。

これを検索しやすい形に整形するのがREINDEXコマンドとなる。

議事録をマインドマップを手で書いて、あとでソフトを使って綺麗にする、みたいなものだ。


まえおき、終わり

Firefoxが使用するDBファイル

Firefoxでは主に以下のファイルがSQLiteDBだ。

ファイル名データサイズ更新度概要
urlclassifier3.sqlite悪意のあるサイトや偽装サイトのデータ
places.sqliteブックマークや訪問履歴
formhistory.sqliteフォームの入力履歴
signons.sqliteパスワードの保存許可設定やパスワード自体
cookies.sqliteCookieデータ
content-prefs.sqliteサイト毎の設定
downloads.sqliteダウンロード履歴
permissions.sqliteCookieや画像読み込みなどの許可設定
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

ブックマーク、訪問履歴を扱っているので更新頻度が高く、履歴の保存日数設定によってはサイズも大きくなる。

再編成第二候補。

再編成することで、ロケーションバーでの補完のパフォーマンスが改善されると思われる。

その他

他はそんなに大きなサイズにはならないと思う。cookies.sqlite辺りはデフォルトでCookieを許可している場合はそれなり溜まるかもしれないが...(私はデフォルトでは許可していないので10KBに満たない)

断片化が進んでいるかの調査方法

sqlite3コマンドが使えるという前提で書く。

以下のコマンドで各値を得る。

ページサイズ(Byte)
PRAGMA page_size
全体ページ数
PRAGMA page_count
空きページ数
PRAGMA freelist_count

ページサイズ * 全体ページ数 ≒ ファイルサイズ である。また断片化が進んでいるほど、空きページ数が大きくなる。

urlclassifier3.sqliteを例にとると

ページサイズ
4096
全体ページ数
6080
空きページ数
567

約10%、2.2MBほどの空きがあることが分かる。

この空きページ数が再編成の一つの指標になると思う。どのくらい断片化すると体感速度に影響が出るのか分からないけど...。

最後に、Webサイトの読み速度などに変化はないはずなので何でも早くなるわけじゃないことに注意。

*1:本棚は自動拡張/縮小とする

*2SQLiteではページ・サイズといい、PRAGMA page_sizeで見ることが可能

elimelim 2009/05/13 00:26 urlclassifier3.sqlite ですが、Mac の場合は
~/Library/Caches/Firefox/Profiles/ランダム文字列.プロファイル名/以下
に、ありました。

necydanecyda 2009/05/13 01:09 linuxです。
~/.mozilla/firefox/ランダム文字列.プロファイル名/
にありました。

secondlifesecondlife 2009/05/13 11:43 urlclassifier3.sqlite はファイル自体を削除したほうが、再度起動時に再作成されますし、サイズも減り、かつ手軽なので、ネットワークが低速な環境以外なら良さそうです。

teramakoteramako 2009/05/13 12:14 >id:elimさん、id:necydaさん
ご報告ありがとうございます。反映しました。

>id:secondlifeさん
たしかに、その手はありますね。
http://firefoxhacks.at.webry.info/200903/article_2.html
によると分割ダウンロードされるので低速環境でもいけるかも。

あ 2009/05/14 16:29 > また断片化が進んでいるほど、空きページ数が大きくなる。

断片化が進んでいるほど空きページ数が大きくなる、とは限りません。

図書館で例えると、ページ → 棚 と考えて、1 つの棚のサイズは固定で、場所が足りなくなれば棚の数を追加する、と考える良いと思います。
そうすると「空きページ」→ 空いてる(1 冊も本が入っていない)棚、です。

例えばすべての棚に、それぞれ 1 冊ずつだけ本が入っていたら、それはものすごく断片化が進んだ状態ですが、その場合の空きページ数は 0 です。

teramakoteramako 2009/05/14 17:01 あう。。。全くもって仰るとおりです。
なんでこんなDBやっている人なら常識とも言える事に気づかなかったんだorz
穴があったら入りたい

重要なご指摘ありがとうございました。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

 |