2016-08-14 11 views
5

私はダッシュボードビューを持っています。これはデータベース全体のテーブルからの小さなデータセットを必要とします。データベースのクエリ(削除されたサブクエリなど)を最適化しました。今度は〜20のクエリが順番に実行され、データベースから異なるデータセットをフェッチしています。ほとんどのHQLクエリにはGROUP BYJOIN句が含まれています。 Spring RESTインタフェースでは、結果はフロントエンドに返されます。Springデータクエリの実行最適化:JpaRepositoryでのHibernate @Queryメソッドの並列実行

カスタムクエリの実行を最適化するにはどうすればよいですか?私の最初の考えは、データベースクエリを並行して実行することでした。しかし、私はそれをどのように達成するのですか?いくつかの研究をした後、私は、パラレルでメソッドを実行することを可能にする注釈@Asyncを見つけました。しかし、これはHibernateのメソッドで動作しますか? JpaRepositoryに@Queryと注釈が付けられたすべてのメソッドに対して常に新しいデータベースセッションが作成されますか?データベースクエリの実行は、結局全体の実行時間に影響しますか?

データベースコールを並行して実行する別の方法は、ダッシュボードコールをいくつかの単一のAjax呼び出しに分割することです(すべての関心事は独自のAjax呼び出しを取得します)。ダッシュボードが開かれるたびに(つまり、日付範囲が変更されるたびに)、別の20個のAjax呼び出しが新しいデータをフェッチするため、私はそれをしたくありませんでした。同じ質問が残っています:SQLクエリを並行して実行することは、データベースの実行時間に影響しますか?

私は現在、データベースにインデックスを追加していません。これは次のもの、私は間違いなくやっています。しかし、私は、クエリを並行して実行することによるパフォーマンスの影響と、これをプログラムでSpringで実現する方法に興味があります。

私のプロジェクトは、当初jHipster(春ブーツ、MariaDB、AngularJSなど)によって生成された

答えて

6

まず、並列にこれらのSQLを実行すると、データベースには影響しませんし、それだけで、ページの読み込みを高速化するため、デザインがされますそれに焦点を当てるべきです。

データが無関係(結合、ビューなどなし)であるため、これらの20個のSQLを結合できないことを前提として、この回答を投稿しています。

@Asyncの使用には2つの理由があります。

理由1 - 非同期タスクは、多数のタスクを起動して忘れたり、すべてのタスクがいつ完了するかを知りたいときに最適です。したがって、すべての非同期タスクが完了するまで待つ必要があります。あなたはどれくらい待つべきですか?最も遅いクエリが実行されるまでは?

チェック(spring.io @ガイドから - https://spring.io/guides/gs/async-method/)非同期のため、このサンプルコード

// Wait until they are all done 
while (!(page1.isDone() && page2.isDone() && page3.isDone())) { 
    Thread.sleep(10); //10-millisecond pause between each check 
} 

ウィル/べき20個の非同期DAOクエリ上のサービス・コンポーネント待ち?

理由2 - Asyncはスレッドとしてタスクを起動していることに注意してください。 JPAで作業するので、エンティティマネージャはスレッドセーフではないことに注意してください。 DAOクラスはトランザクションを伝播します。ここでは、問題を起こす可能性のある問題の例を示します。http://alexgaddie.blogspot.com/2011/04/spring-3-async-with-hibernate-and.html

IMHO、複数のAjax呼び出しを実行する方がよいでしょう。それはコンポーネントを結束させるためです。はい、20個のエンドポイントがありますが、より簡単なDAO、簡単なSQL、容易にユニットテスト可能で、返されたデータ構造はAngularJSウィジェットによって処理/解析が容易になります。UIが20回のAjax呼び出しをすべてトリガーすると、ダッシュボードは、同時にすべてをロードするのではなく、準備ができたら個々のウィジェットをロードします。これは、ダッシュボードの読み込み速度を遅くする(キャッシング、インデックス作成など)最適化を行うことで、将来デザインを拡張するのに役立ちます。

DAO呼び出しを束ねるだけで、データ構造が複雑になり、単体テストがより困難になります。

+1

ありがとうございます。残念ながら私はあなたに完全な恩恵を与えるには遅すぎました。 –

3

通常、クエリを並行して実行する方がはるかに高速です。 Springデータを使用していて、JPAプロバイダ(Hibernate)が特定のものを設定しない場合、データベースへの接続を格納する接続プールが作成されます。私はデフォルトでHibernateが10の接続を保持していると思いますので、10個のクエリを並行して実行する準備ができています。パラレルで実行することによってクエリがどれだけ速くなるかは、データベースとテーブル/クエリの構造によって異なります。 @Asyncの使用はベストプラクティスではないと思います。特定のクエリの結果を提供する20のRESTエンドポイントを定義する方がはるかに優れたアプローチです。これにより、クエリごとにEntity、Repository、RestEndpointクラスを簡単に作成できます。そうすることで、各クエリは分離され、コードはそれほど複雑ではありません。

関連する問題