1

ローカルH2データベースにデータを保持するデスクトップアプリケーションがあります。Squerylを使用してデータベースに接続しています。

データベースのサイズは非常に小さいです(約10kB)。深刻なパフォーマンスの問題が発生しており、大量のディスクIOが実行されています。私はDBを読んでいるだけなので、完全なデータをキャッシュできると思っていました。キャッシュサイズをある値に設定することもできます(合計データベースサイズよりもはるかに大きい)。また、ロックを無効にしてみましたが、結果はありませんでした。

私のプログラムは、データベースに対して非常に多くの小さなクエリを実行します。TableModel基本的に、すべてのテーブルエントリ(各行の各列)に対してクエリを実行するSwingがあります。これらの各呼び出しをSqueryltransactionブロックにラップしています。

JVisualVMを使用してプロファイルを作成しましたが、次の呼び出しツリーに問題があると思われます。一番上の方法は、私のコードからの読み取りアクセスです。

JVisualVMスクリーンショットへのリンク。

質問

どうすればこれを修正できますか、または何が間違っていますか?どういうわけか、1MB未満のメモリに保持できるほど小さいDBに対して多くの小さな呼び出しを行うことができるはずです。このディスクIOが発生しているのはなぜですか?どうすれば回避できますか?

4

2 に答える 2

3

getValueAt()スクリーショットを見ると、TableModelのメソッド内のDBから選択しているようです(getRowAt()呼び出しスタックの最上位にあるメソッド名が、この仮定を引き起こします)。

私の仮定が正しければ、これがあなたの主な問題です。getValueAt()JTableのpaint()メソッドによって常に(おそらく1秒間に数回)呼び出されるため、可能な限り高速にする必要があります。

JTableのデータを単一のSQLクエリで取得し、その結果をいくつかのデータ構造(たとえば、ArrayListなど)に保存する必要があります。

Squerylはわかりませんが、すべてのSELECTをトランザクションにラップする必要があるとは思えません。スタックトレースから、これによりH2に大量の書き込みが発生するようです。毎回トランザクションを明示的に開く(および閉じる)ことなく、SELECTを実行しようとしましたか?

于 2012-01-14T21:55:26.923 に答える
1

解決策は最終的には非常に単純でした。FAQを引用します。

データベースのクローズの遅延

通常、データベースへの最後の接続が閉じられると、データベースは閉じられます。状況によっては、これによりアプリケーションの速度が低下します。たとえば、少なくとも1つの接続を開いたままにすることができない場合などです。データベースの自動クローズは、SQLステートメントを使用して遅延または無効にすることができますSET DB_CLOSE_DELAY <seconds>。このパラメーター<seconds>は、データベースへの最後の接続が閉じられた後、データベースを開いたままにしておく秒数を指定します。次のステートメントは、最後の接続が閉じられてから10秒間データベースを開いたままにします。

SET DB_CLOSE_DELAY 10

この値-1は、データベースが自動的に閉じられないことを意味します。この値0はデフォルトであり、最後の接続が閉じられたときにデータベースが閉じられることを意味します。この設定は永続的であり、管理者のみが設定できます。データベースURLに値を設定することができます:jdbc:h2:~/test;DB_CLOSE_DELAY=10

于 2012-01-16T21:27:54.927 に答える