Spring-boot アプリケーションでは、JPA と Hibernate を使用しています。
JPAリポジトリで定義されたパラメーター化されたIN句を使用したカスタム選択クエリメソッドがあります。データが膨大であるため、パラメーターとして渡された ID の小さなバッチを使用して、同じクエリを複数回実行しています。しかし、パフォーマンスを向上させることはできません。
約 200000 件のレコードがあり、所要時間は 1 分です。これは非常に巨大です。
以下は私が疲れたものです
- POJO全体ではなく、必要な列のみを選択すると、クエリ時間が8秒短縮されました
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
そして、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 接続の取得時間を回避する方法はありますか?