在 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集合)
即使使用 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 连接获取时间?