現在、アプリケーションを高速化する方法を調査しており、その大部分はエンティティのリスト(実際はテーブル)に関連しています。ソートされたデータのジョインによるHibernateページング
パラメータと要件
そのリストのパラメータと要件は(私はここでは関係のものを言及しようとするでしょう)次のとおりです。
- 50万行がある場合もあります/リスト内のエンティティ
- 一度に表示されるのは2つだけです。ここでページネーションを使用します。
- ユーザーはリストに表示する列を選択できます(したがって、単一の「静的」なクエリを提供することはできません)。
- これらのリスト列のほとんどは、ソート可能および/またはフィルタリング可能です。
- エンティティには、リスト列のいくつかを提供する2対多関係があります。
- これらのリスト列には、複数の値を含むことができます(これらは1つのセル内にリストとして表示されます)
- 現在のユーザーの操作(編集、アップロードなど)に起因するデータの更新は、 (JPAのように)、以下の単純化されたエンティティを考えるモデルが少し明確にするために、できるだけ速くリスト(すなわち「immeditately」)
モデル:
class Car {
String manufacturer;
String model;
Date dateOfProduction;
List<TyreSize> allowedTyreSizes;
Set<Date> inspectionDates;
}
はしようとしないでください。それがjuだからあまりにも多くの意味をそのモデルに入れてstは問題を説明するためのものです(私たちのデータは、はるかに複雑ではありません)。ユーザーは、我々は、動的に必要なクエリを構築している、実行時に表示する列を選択することができますので
+==============+=======+=======+===============+=============+
| Manufacturer | Model | Prod. | Allowed Tyres | Inspections |
+==============+=======+=======+===============+=============+
| BMW | 320d |01/2016| - 225/40 R18 | - 01/07/16 |
| | | | - 225/45 R17 | - 13/12/16 |
+--------------+-------+-------+---------------+-------------+
| Toyota | Camry |09/2016| - 185/70 R13 | - 31/12/16 |
+--------------+-------+-------+---------------+-------------+
:車の
「完全な」リストには、このようになります。それは今のところかなりうまくいっています。
基本的な問題
ソートやフィルタリング関与しているときに我々が抱えている問題はパフォーマンスです:我々の現在のアプローチは、ソートし、メモリにフィルタリングするために必要なすべてのデータをロードすることで、そこにソートやフィルタリングを行うと、並べ替えられたIDとそのページのリストを保持します。我々はこれがやや遅いことを認識していますが、これまでのところパフォーマンスは経営陣を満足させるほど十分でした。状況が変化しましたが、現在はより多くのデータを処理し、パフォーマンス要件が向上しています。
-
:したがって
- ダイナミックな列を持ち、潜在的にセルごとに複数の値を持つ多数の行のページングは、どのようにして最適な方法になりますか?
我々は現在、私はまだこの(側)質問をするよデータベースでそれを行うためのアプローチを以下している間にすべてのデータのADNのソートやフィルタリング改善する方法を調査しています
現在、私たちはPostgreSQLを使用していますが、可能であればそれを使い続けたいと思いますが、別のストレージがはるかに適している場合は、少なくともチェックしてください。
(下部)アプローチと質問(複数可)現在
前述したように、私たちは現在、データベースのソート、フィルタを持っており、我々のデータをページ付けしようとしています。 2つのクエリを使用しても問題ありません.1つは現在のページの行IDを取得するクエリであり、もう1つは実際にそれらの行のデータを読み込むクエリです。
挑戦は、私はそれに集中します最初のクエリがあるので:理論このクエリでは
SELECT DISTINCT id FROM (
SELECT id, ... FROM car c
LEFT OUTER JOIN allowedtyresizes ats ON c.id = ats.car_id
LEFT OUTER JOIN tyresizes ts ON ts.id = ats.tyresize_id
... //additional joins if required
ORDER BY ... //apply any user-defined sorts
WHERE ... //apply any user-defined filters (or maybe put them into the joins)
)
OFFSET ... //page offset
LIMIT ... //page size
:我々はSQLでこのような何か(上の車の例を使用)を行うことができ
私の知る限り(それは完全ではないかもしれませんが)現在のページにロードする行を特定するために必要な結果を提供する必要があります。
私たちはHibernate(5.2 atm)を使用しているので、これを達成するためにHQLまたはCriteriaを使用したいと思います。しかし、Hibernateが上記のようなselectステートメントからの選択をサポートしていないかのように見えます。したがって、実行可能なアプローチではないかもしれません。ネイティブSQLや全く異なるアプローチに落ちなければならない場合は、現在のインフラストラクチャと連携させることをお勧めします。
だから、質問は以下のとおりです。
- は、「選択から選択して」のような5.xのサポート何かを休止していますか?
- ソートとフィルタリングを多対多リレーションシップで行う必要がある場合、つまり、単一のジョインで重複行が発生する可能性がある場合、Hibernateを使用するページネーションはどのように行われますか?
HQLを使用してクエリを渡すことで、クエリを実行します。 –
@GauravSrivastavはい、私たちはSQLクエリの実行方法を知っています。しかし、クエリが非常に複雑になり、動的に作成されるため、Hibernateが既に使用できるものを提供しているのではなく、そのようなクエリを構築するために必要な情報を抽出するために、 – Thomas
あなたのモデルはどれくらい複雑ですか?データベースビューを使用してエンティティをバインドすることで、おそらく最高のパフォーマンスが得られます。悪い点は、データベースビュー(新しいRDBMSのサポートを開始する場合は別のバージョン)を手作業で書く必要があることです。良いことは、エンティティがよりシンプルになり、Hibernateがパフォーマンスの低いSQLを生成する機会が少なくなることです。 –