32

Querydsl 、jOOQJEQUELactivejdbciciqlなど、Javaで使用できるさまざまなQueryDSLライブラリ間のパフォーマンス比較に関するリソースを教えてもらえますか。

背景: Spring JDBCテンプレートを使用していますが、それでもクエリをプレーンな文字列形式で記述する必要がありました。直接クエリの記述に問題はありませんが、DBテーブル名に直接依存しているのではないかと心配しています。HibernateやJPA/EclipseLinkのようなORMフレームワークは使いたくありません。可能な限り高い生のパフォーマンスが必要です(IMO、CRUD中心のアプリケーションに適しています)。これらのDSLのオーバーヘッドは、それが少しの場合にのみ余裕があります(ほとんどの場合、StringBuilder / Stringの連結になると思います!)

一部のxmlで外部化された名前付きクエリの使用を検討しました。しかし、さまざまなクエリDSLライブラリが提供する価値を評価しようとしているだけです。

編集:私の要件の詳細: APIメソッドを使用して適度に複雑なクエリを構築する場合のこれらのパフォーマンスの比較を知りたいです。必要なのは、これらのクエリDSLライブラリのいずれかを使用してクエリ文字列を生成し、それをSpringJDBCテンプレートに渡すことだけです。したがって、この中間ステップを追加するとパフォーマンスが大幅に低下するかどうかを知りたいので、名前付きクエリを使用するか、StingBuilderまたは同様のアプローチを使用する独自のライブラリを構築します。

jOOQ、iciql、QueryDSLでの私の経験を更新してください:

元の投稿でこれについて言及しなかったものの、エンティティクラスで必要な使いやすさとオーバーヘッド(追加のアノテーションや実装が必要な場合など)にも熱心です。

jOOQ:

  • エンティティのプロパティをライブラリ固有の方法に変更する必要があります
  • SQLクエリ文字列を返すことができます

Iciql:

  • エンティティは変更なしまたはほとんど変更なしでマッピングできます(合計3つの方法を使用してマッピングできます)
  • ただし、クエリの選択のみに制限されます(更新/削除/ ...の場合は、エンティティを再度変更する必要があります)

QueryDSL:

  • エンティティをテーブルにバインドする複数の方法(ライブラリ固有の方法以外で、JPAアノテーションの使用がサポートされています)。しかし、少なくともエンティティを変更する必要があります
  • クエリ文字列を取得する簡単な/直接的な方法はありません

(すべての観察結果は、私がこれらについて知っている知識がほとんどありません。これらのいずれかが正しくない場合は、修正してください)

上記のすべてで、私は名前付きクエリを書くことに固執しています:(しかし、Lukas Ederの回答は私の元の投稿の懸念(パフォーマンス)について説明しているようですので、私は彼を受け入れました。

4

4 に答える 4

29

最近のJVMでは、SQL文字列の連結についてあまり心配する必要はありません。データベース抽象化レイヤーが生成する可能性のある真のオーバーヘッド(データベースへの往復時間と比較して)は、通常、Hibernate/JPAで実行される第2レベルのキャッシュが原因です。または、インデックスや一般的なクエリ変換の使用が不可能になるような方法で、オブジェクトモデルをSQLに非効率的にマッピングすることによって。

UNIONsそれと比較すると、文字列の連結は、いくつかのネストされた、、、SELECTsなどJOINssemi-JOINs含む複雑なSQL構造の場合でも、実際には無視できますanti-JOINs。したがって、言及したすべてのフレームワークは、制御を維持できるため、同様の方法で実行されると思います。あなたのSQL。

一方、一部のフレームワークまたはそれらのフレームワークの使用モードは、実際には結果セット全体をメモリにフェッチする場合があります。結果セットが大きい場合、これは問題を引き起こす可能性があります。また、Javaのジェネリックでは、ほとんどのプリミティブ型(、、intなど)が対応するラッパー( 、 )longにマップされている可能性があります。IntegerLong

jOOQ (私は開発者です)に関しては、以前にYourKit Profilerを使用してライブラリのプロファイルを作成し、大量クエリを実行しました。大量の作業は、クエリの作成ではなく、常にデータベースで行われました。jOOQは、StringBuilderクエリごとに1つを使用します。私は(検証されていませんが)QueryDSLJEQUELが同じことをしていると想像しています...

JaQuのフォークであるiciqlについては、Javaインストルメンテーションを使用して自然な構文を逆コンパイルするという事実によって追加の影響がある可能性があります。しかし、それがあまりにも大きな影響を意味するのであれば、それは省略できると思います。

于 2011-08-31T08:30:39.143 に答える
6

MyBatisステートメントビルダーもご覧ください。

MyBatisは明らかにマッピングテクノロジーですが、MyBatisから切り離されているように見えるStatement Builder DSLがあります(つまり、ビルダーを使用するためにMyBatisから他に何も必要ありません...迷惑なことにそれ自体のjarにはありません)。ThreadLocalsを使用しているので、私はそれが好きではありません。

于 2012-05-01T18:25:02.503 に答える
2

他のフレームワークについて話すことはできませんが、 ActiveJDBCとHibernateを比較するためにパフォーマンスの基本的な分析を実行しました。テストは、MySQLに対して8G RAM、SSDドライブを搭載したラップトップで行われました。いくつかの単純な列と代理IDPKを持つテーブルPEOPLE。

1つのテストは、50Kレコードをオブジェクトとして挿入することであり、もう1つは、テーブルから(メモリ内で)一度に50Kオブジェクトを読み取ることでした。どちらのテストでも、ActiveJDBCはHibernateよりも40%パフォーマンスが向上しました。いずれの場合も、生成されたクエリは単純な挿入と選択であり、互いに非常によく似ています。

お役に立てれば、

イゴール

于 2011-09-01T22:44:02.703 に答える
1

プログラムによるSQLクエリ作成用の軽量で依存関係のないライブラリは、OpenHMSSQLBuilderライブラリです。

https://openhms.sourceforge.io/sqlbuilder/

Maven依存関係として利用可能:

https://mvnrepository.com/artifact/com.healthmarketscience.sqlbuilder/sqlbuilder

于 2019-01-31T16:14:06.803 に答える