4

特にトランザクションに関して、サイトの SQLite パフォーマンスを改善することを検討しています。本質的に、私が探しているのは、データベースへの書き込みをプロセス内で延期して、すべてを一度に実行できるようにする方法です。ただし、更新クエリを蓄積している間、他のプロセスがデータベースからの読み取りと書き込みの両方を実行できるようにし、プロセスでコミットが発行されたときにのみ書き込み用にファイルをロックしたいと考えています。

ドキュメントを見ると、トランザクションで更新コマンドが発行されると、プロセスは RESERVED ロックを取得するように見えます。これは、(私の記憶が正しければ) 更新クエリを独自のトランザクションに追加しようとする他のプロセスを意味します。またはトランザクションをコミットすることはできないため、トランザクションがロックされたプロセスでコミットされるまでブロックされます。

この特定の機能には、データの整合性に関する非常に優れた理由があると確信しています。私が言えることは、私の場合、これらの更新を同時に実行しても危険はないということだけです。

1 つの解決策は、各プロセスで呼び出したいクエリのテキストを配列に蓄積し、書き込みの準備ができたらループダウンすることですが、SQLite トランザクションを実行できるかどうか疑問に思っています。これを自動的に行ってください。

更新:「すべての更新を一度に行う」というのは、基本的に SQLite でトランザクションを使用して、クエリごとではなく、プロセスごとに 1 回だけ排他ロックを取得してディスクに書き込むことです。これにより、SQLite を使用すると 100 倍のスピードアップが実現します。

いくつかの基本的なテストを行ったところ、トランザクションにクエリを追加する複数のプロセスがあると、そのプロセスが RESERVED ロックを取得しようとする更新クエリにヒットしたようです。予約されたロックを持つことができるプロセスは 1 回だけであるため、ロックを取得しようとする他のプロセスは、ロックを持つプロセスがトランザクションを終了するまでブロックされます。

私はまだパフォーマンスの低下に遭遇していないので、この問題は時期尚早の最適化である可能性があることを認めますが、いくつかの簡単なテストを実行し、100 人のユーザーがそれぞれ 100 個のクエリを使用してトランザクションを作成および実行するのに、私のマシンの PHP で約 4 秒かかりました。

4

2 に答える 2

3

SQLite は、 あるデータベースを別のデータベースに接続するためのATTACHをサポートしています。おそらく、データを別のデータベースに蓄積し、蓄積された行をマージする準備ができたら、別のデータベースをアタッチし、単一のステートメントで行をコピーして、デタッチすることができます。

編集: OP と同様の提案が sqlite-users のメーリング リスト スレッドで行われ、いくつかのフォローアップ ディスカッションが行われました。

于 2008-11-15T01:43:20.253 に答える
1

データベースをアタッチするよりも、一時テーブルを作成する方がよいでしょう。(一時的に作成...)

また、新しい WAL ジャーナル モードを見てみましょう。これは、手動でやろうとしていることを正確に実行し、同時書き込みと読み取りを許可します (ただし、同時書き込みではありません)。

#pragma journal_mode=WAL

于 2010-12-21T10:16:55.110 に答える