8

関連する質問:マルチスレッド アプリケーションで SQLite を使用する方法。

私は、マルチスレッド プログラムで SQLite3 からまともなパフォーマンスを得ようとしています。書き込みレイテンシを除いて、そのパフォーマンスには非常に感銘を受けました。それは問題ではありません。ディスクが回転してデータをコミットするのを待つ必要があります。しかし、キャッシュから読み取ることができたとしても、これらの書き込み中に読み取りがブロックされることは、かなり耐えられません。

私の使用事例では、インデックス付きフィールドによって 1 つの小さなオブジェクトを取得するために多数の小さな読み取り操作が含まれますが、これらの操作は多数あるため、これらの操作には待機時間が重要です。書き込みは大きく、1 つのトランザクションに蓄積されます。書き込みが完了するため、読み取りに大きなレイテンシが発生することは望ましくありません。

最初に、ミューテックスを使用して単一の接続を使用して保護しました。ただし、書き込みスレッドがトランザクションの完了を待機している間は、ライターがミューテックスを解放するまでミューテックスを取得できないため、リーダーはディスク I/O でブロックされます。複数の接続を使用しようとしましたが、 から取得SQLITE_LOCKEDsqlite3_stepます。つまり、すべての読み取りコードを再設計する必要があります。

私の書き込みロジックは現在次のようになっています。

  1. 接続ミューテックスを取得します。
  2. START TRANSACTION
  3. すべての書き込みを行います。(通常、小さいものは 10 ~ 100 個です。)
  4. END TRANSACTION-- ここでブロックします
  5. ミューテックスを解放します。

私が知らない解決策はありますか?SQLITE_LOCKEDエントリがキャッシュにある場合、読み取りコードをすべて書き換えて処理、リセット、および再試行する必要がなく、ディスクの回転が完了するのをリーダーが待たないようにする簡単な方法はありますか?

4

2 に答える 2

6

複数のリーダーと 1 つのライターが同時にデータベースにアクセスできるようにするには、先行書き込みログを有効にします。

WAL は小さなトランザクションでうまく機能するため、書き込みを蓄積する必要はありません。

WAL はネットワーク化されたファイル システムでは機能しないことに注意してください。最適なパフォーマンスを得るには、定期的なチェックポイントが必要です。

于 2013-01-10T08:01:19.920 に答える
1

まず第一に、sqliteはそれ自体でマルチスレッドサポートを提供します。プログラム全体の速度を低下させるだけなので、独自のミューテックスを使用する必要はありません。疑問がある場合は、sqliteスレッドオプションを参照してください。

ログ先行書き込みを使用すると問題が解決する場合がありますが、それは両刃の剣です。読み取りが進行中である限り、挿入されたデータはメインデータベースファイルに書き込まれず、WALジャーナルは大きくなります。これについては、先行書き込みログで詳しく説明されています

アプリケーションの1つでWALモードでsqliteを使用しています。少量のデータの場合はうまく機能します。ただし、データが多い場合(1秒あたり数百の挿入、ピーク時にはさらに多く)、sqlite構成をいじっても修正できないと思われる問題が発生します。

あなたが考えるかもしれないのは、それぞれが特定の期間に割り当てられたいくつかのデータベースファイルを使用することです。これは、クエリが時間に依存する場合にのみ適用されます。

私はおそらく先を走りすぎています。WALジャーナルが役立つはずです:)

于 2013-01-10T08:23:04.463 に答える