2

Spring-boot アプリケーションでは、JPA と Hibernate を使用しています。

JPAリポジトリで定義されたパラメーター化されたIN句を使用したカスタム選択クエリメソッドがあります。データが膨大であるため、パラメーターとして渡された ID の小さなバッチを使用して、同じクエリを複数回実行しています。しかし、パフォーマンスを向上させることはできません。

約 200000 件のレコードがあり、所要時間は 1 分です。これは非常に巨大です。

以下は私が疲れたものです

  1. POJO全体ではなく、必要な列のみを選択すると、クエリ時間が8秒短縮されました
  2. Hibernate の統計を分析したところ、次のログが見つかりました。

    ( 1 個の JDBC 接続の取得に 382016470 ナノ秒、0 個の JDBC 接続の解放に 0 ナノ秒、1 個の JDBC ステートメントの準備に 798909958 ナノ秒、1 個の JDBC ステートメントの実行に 305523944 ナノ秒、0 個の JDBC バッチの実行に 0 ナノ秒、0 個の L2C プットの実行に 0 ナノ秒、0 0 個の L2C ヒットの実行に費やされたナノ秒; 0 個の L2C ミスの実行に費やされた 0 ナノ秒; 0 個のフラッシュの実行に費やされた 0 ナノ秒 (合計 0 個のエンティティと 0 個のコレクションのフラッシュ); 0 個の部分フラッシュの実行に費やされた 0 ナノ秒 (合計 0 個のエンティティと 0 個のフラッシュのフラッシュ)コレクション)

Hikari接続のPoolでもJDBC接続の作成に時間がかかります。以下は光のプロパティです

 spring.datasource.hikari.connection-timeout=120000
    spring.datasource.hikari.maximum-pool-size=100
    spring.datasource.hikari.minimum-idle=30
 spring.jpa.hibernate.connection.provider_class=org.hibernate.hikaricp.internal.HikariCPConnectionProvider
    spring.datasource.hikari.pool-name=HikariConnectionPool
    spring.datasource.hikari.data-source-properties.cachePrepStmts=true
    spring.datasource.hikari.data-source-properties.useServerPrepStmts=true
  1. そして、JPAクエリごとにJDBC接続が確立され、準備されます。次のプロパティを設定した後でも

    spring.datasource.hikari.data-source-properties.cachePrepStmts=true spring.datasource.hikari.data-source-properties.useServerPrepStmts=true

IN句のパラメータ数は一定にしています

コード スニップネット

//JPA Reposistry

public interface CarRepository extends CrudRepository<Car, String>, JpaSpecificationExecutor<Car> {

@Query(SELECT u.carName as carName,
    u.carId as
    carId from
    Car u
    where u.carId in (:carIds))
List<CarP> findCarProjections@Param("carIds")Set<String> carIds);

}

//Service
    @Component public carService

{
@Autowired
CarRepository carRepo;

public void processCars(List<carId> carIds)
{

List<List<String>> carIdPartioned = partionCarIds(carIds)
ExecutorService es = Executors.newFixedThreadPool(10);
for(List<String> carIdPart : carIdPartioned)
es.submit(new ProcessCarInThread(carIdPart,carRepo));

}

//Each Call Creates a new connection to JDBC 
//Takes time to prepare Statement ( as given in hibernate statics )
class ProcessCarInThread implements Runnable
{
List<String> carIds;
CarRepository carRepo;
public ProcessCarInThread(List<String> carIds, CarRepository carRepo )
{
this.carIds=carIds;
this.carRepo=carRepo;
}
       @Override
    public void run() {
//query 1
List<CarP> cars=carRepo.findCarProjections(carIds);
//query 2
List<SomeotherEntity> cars=otherRepo.findSomethingElse(params);
//even query 1 and query2 is not executing in a single JDBC connection
//Do Something
}

}

パフォーマンスを改善したいのですが、提案は大歓迎です。

JDBC クエリの準備時間または JDBC 接続の取得時間を回避する方法はありますか?

4

1 に答える 1