簡體   English   中英

如何在單個 JDBC 連接中執行多個 JPA 查詢

[英]How to Execute multiple JPA queries in a single JDBC Connection

在 Spring-boot 應用程序中,我使用 JPA 和 Hibernate。

我有一個自定義 select 查詢方法,在 JPA 存儲庫中定義了參數化的 IN 子句。 由於數據量很大,我正在執行多次相同的查詢,並將小批量的 ID 作為參數傳遞。 但我無法提高性能。

大約有 200000 條記錄,所用時間為 1 分鍾。 這是非常巨大的。

以下是我累的事情

  1. 只選擇所需的列,而不是整個 POJO -> 確實將查詢時間減少了 8 秒
  2. 當我分析 Hibernate 靜態數據時:以下是找到的日志:

    ( 382016470 nanoseconds spent acquiring 1 JDBC connections; 0 nanoseconds spent releasing 0 JDBC connections; 798909958 nanoseconds spent preparing 1 JDBC statements; 305523944 nanoseconds spent executing 1 JDBC statements; 0 nanoseconds spent executing 0 JDBC batches; 0 nanoseconds spent performing 0 L2C puts; 0執行 0 個 L2C 命中所花費的納秒;執行 0 個 L2C 未命中所花費的 0 納秒;執行 0 個刷新所花費的 0 納秒(總共刷新 0 個實體和 0 個集合);執行 0 個部分刷新所花費的 0 納秒(總共刷新 0 個實體和 0 個集合)

即使使用 Hikari 連接池,創建 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 連接獲取時間?

非常令人驚訝的是,在我當前的應用程序后 PROD 部署中也遇到了類似的性能問題。 幸運的是,我們能夠修復它。

根本原因:我們觀察到在@Query 中使用多個輸入參數會導致性能問題。

@Query(SELECT u.carName as carName, u.carId as carId from Car u where u.carId in (:carIds))

解決方案:使用entityManager代替動態形成類似的查詢,並顯着提高性能是觀察到的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM