2

ここに環境: 組み込みの h2 データベースに基づく顧客向けのアプリケーションをプログラムし、テストを行う前に最新バージョンにアップグレードしました。データベースは、29 個のテーブルと 26 個のビューで構成されています。26 個のビューのうち、Java で実際に「使用」されているのは 8 個だけで、マップされたビューは pojo に休止状態になります。他のビューは、いくつかの値を集計してからいくつかの列でグループ化するなど、他のビューのバックグラウンド計算を行っているだけです。これらのビューでは多くの計算が行われます。お気に入りのツール (h2 コンソールなど) を使用してデータベース テーブルを簡単にチェックし、計算にエラーがあるかどうかを確認できるため、java で計算しないことにしました。そのため「CASE WHEN ... END」が多い。その行の単一の列が NULL になると、hibernate は常にすべての列に NULL 値を持つ行全体を返すため、これらのビューのステートメント。私たちもその問題を特定することはできませんでした...それにもかかわらず、NULL、0、および 0.0 をチェックする必要がある計算にも除算があったためです。一部の中間値が別の場所で使用される場合があるため、ビューは「スタック」されます。しかし、6 つのビューの「スタック」を使用する別のビューにも基づく 1 つの最終的なビューの「下」には、7 つのビューの「スタック」が常に存在します。一部のビューは同じですが、一部は同じではありません。

さて、ここで問題が発生 します。「興味深い」テーブルのデータベースにいくつかの (20 のような) レコードを挿入すると、1 つのビューがデータ (4 つの集約された行) を約 1 秒で配信します。400ms。それは私たちにとっては問題ありません。データを約 500 ~ 2000 レコードにスケールアップすると、特別なビュー (約 25 の集計行を配信) でデータを配信するのに 1 時間 (1 時間) 以上かかります。マシンは、8GB の RAM (-Xmx2G および -Xms1G) CPU 2.66GHz (Intel(R) Core(TM)2 Quad CPU Q8400 @ 2.66GHz) を搭載した Linux または 4GB の RAM (-Xmx1G - Xms512m) CPU は不明ですが、おそらくシングル/デュアル コア @ 2GHz です。

これまでの私の分析: アプリケーションのメモリ使用量を追跡しましたが、それは主要な問題ではないようです。長時間実行されているクエリ中にスタック トレースを調べると、hibernates getEntityManager().createQuery(getCriteriaQuery()).getResultList() へのエントリ ポイントより下 (!) まで (場合によっては) 最大 100 レベルのスタック深度があることがわかりました。明らかな「時間消費者」は org.h2.table.TableFilter/Table/TableView.getBestPlanItem と org.h2.table.Plan.calculateCost と org.h2.index.ViewIndex.getCost です。すべてのビューですべての結合をチェックして、欠落しているインデックス、1 つが見つかり、追加されましたが、成功しませんでした。

私のテスト: すべてのデータとスキーマを同じ Linux マシン (微調整されていないバニラ) 上の PostgreSQL (8.1) に転送し、そこでテストを実行しました (vaccuum または reindex を実行する前に!)。6秒 h2で約1時間かかった同じデータを含む同じビューの場合。

今、私は本当にデータベースを切り替えたくありませんが、誰かが良い考えを持っていない限り、それは究極の選択肢です...

注意: 私が発見したことは次のとおりです: h2 の information_schema でビューを確認すると、ビュー自体を分析するかなりの作業を行っていることがわかります。私のSQLスクリプトのすべてのビューは、20行から120行(約)です。情報スキーマの「コンパイルされた」ビューは、2KBytes から 3MBytes (つまり、メガバイト) の範囲です。上記のものは、ほぼ 400k です...おそらく、これも問題の一部です...

OK、それはすべての人々です。私はどんな助けにも優雅です。あらゆる場所で hibernate と CriteriaQuery を使用しているため、データベースを切り替えても構わないと思っています。そのため、唯一の作業は、jdbc コネクタを切り替え、ビューのコードを変更することです (既に行われていますが、本番前に 2 回確認する必要があります)。顧客のデスクトップ PC (irk) の PostgreSQL または MSDE は、MS 更新プログラムが MSDE を破損したままにするか、何らかの理由でデータベースが起動しないために発生する可能性のある他の不要なエラーにつながります ...

よろしく、ホルガー

4

1 に答える 1

1

クエリ/ビューは、H2がそれらを最適化するには複雑すぎるかもしれませんが、詳細(問題を再現するためのコード)を知らずに言うのは難しいです。PostgreSQLのオプティマイザーはH2オプティマイザーよりも優れています。おそらく、追加のインデックスを作成する必要があります。これを分析するには、パフォーマンスの最適化とインデックスに関するドキュメントを読むことをお勧めします。

于 2012-04-19T15:55:47.927 に答える