[英]How to Execute multiple JPA queries in a single JDBC Connection
在 Spring-boot 應用程序中,我使用 JPA 和 Hibernate。
我有一個自定義 select 查詢方法,在 JPA 存儲庫中定義了參數化的 IN 子句。 由於數據量很大,我正在執行多次相同的查詢,並將小批量的 ID 作為參數傳遞。 但我無法提高性能。
大約有 200000 條記錄,所用時間為 1 分鍾。 這是非常巨大的。
以下是我累的事情
當我分析 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
並且對於每個 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.