2012-11-15 29 views
5

私はアプリケーションが組み込みLinux上で動作しています。 私は、それぞれにたくさんの行(何千)と52の列を持ついくつかのテーブルを持つ、あらかじめ構築されたDBを持っています。実行時に 'INSERT'を実行するとディスクの断片化が発生することになるので、代わりに最初に多くのゴミを持つDBを構築することを心配しているため、DBを構築しました。INSERTと実行時私は 'UPDATE'を使う。SQLite WALのパフォーマンス向上

私は3秒ごとにDBに多くのデータを書きますが、書き込み手順が高速になるためには、SQLiteでWALモードを使用します。しかし、私はパフォーマンスの問題があります。チェックポイントが発生するたびに時間がかかり、プロセッサは3秒以内に処理を実行できないようです。 これを改善するために、私は10回の書き込み呼び出しの後に、メインスレッドからメッセージキューを受け取り、チェックポイントを行うスレッドを作成しました。

さて、状況は良くても、WALファイルはますます大きくなっているようです... どうすればこの問題を回避できますか?

答えて

5

断片化を避け、データを事前に挿入する必要がなくなるように、sqlite3_file_control()SQLITE_FCNTL_CHUNK_SIZEを使用してチャンクサイズを設定する必要があります。大量のチャンク(一度に1MB)でデータベースファイルの領域を割り当てると、ファイルシステムの断片化が軽減され、パフォーマンスが向上するはずです。 MozillaプロジェクトはFirefox/Thunderbirdのcurrently using this settinggreat successです。

WALについて。多くのデータを頻繁に書いているのであれば、書き込みをより大きなトランザクションにラップすることを検討する必要があります。通常、すべてのINSERTは自動的にコミットされ、SQLiteはデータが実際にディスクまたはフラッシュにフラッシュされるまで待たなければなりません。これは明らかに非常に遅いです。 1つのトランザクションに複数の書き込みをラップすると、SQLiteはすべての単一の行を気にする必要はなく、一度に多くの行をフラッシュできます。 可能であれば、少なくとも数百回の書き込みを1回のトランザクションにラップしようとします。

私の経験では、フラッシュ上のWALは実際にはうまく機能していないため、古いジャーナリングモードに固執するほうが有益です。たとえば、Android 4はSQLiteデータベースにWALモードを使用していないため、おそらく理由があります。あなたが気づいたように、WALは状況によっては縛られることなく成長する傾向があります(ただし、取引がほとんど行われない場合も起こりますので、しばらくしてください)。

+1

これは、データベースファイルのファイルスペースの割り当てに影響することに注意してください。私がWALファイルへの割り当てがチャンクサイズを尊重しないと分かっているからです。 –

1

WALモードでは、SQLiteは変更されたページを-walファイルに書き込みます。 チェックポイントの間だけ、これらのページがデータベースファイルに書き戻されます。

-walファイルは、同時読み取りがない場合にのみ切り捨てられます。

sqlite3_wal_checkpoint_v2SQLITE_CHECKPOINT_RESTARTと呼び出すか、PRAGMA wal_checkpoint(RESTART)を実行してWALファイルを明示的に消去することはできますが、同時読み取りがあると失敗します。

+0

それは私の質問に答えていないようです。 –

関連する問題