В приложении Spring-boot я использую JPA с Hibernate.
У меня есть собственный метод запроса select с параметризованным предложением IN, определенным в репозитории JPA. Поскольку данные огромны, я выполняю несколько раз один и тот же запрос с небольшими пакетами идентификаторов, передаваемых в качестве параметров. Но я не могу улучшить производительность.
Есть около 200000 записей, а время заняло 1 минуту. Который очень Огромный.
Ниже приведены вещи, которые мне надоели
- Выбор только нужных столбцов вместо всего POJO -> сократил время запроса на 8 секунд
При анализе статики Hibernate: были найдены следующие журналы:
(382016470 наносекунд потрачено на получение 1 соединения JDBC; 0 наносекунд потрачено на освобождение 0 соединений JDBC; 798909958 наносекунд потрачено на подготовку 1 оператора JDBC; 305523944 потрачено наносекунды;выполнение 1 операторов JDBC; 0 наносекунд, потраченных на выполнение 0 пакетов JDBC; 0 наносекунд, потраченных на выполнение 0 операций L2C; 0 наносекунд, потраченных на выполнение 0 попаданий L2C; 0 наносекунд, потраченных на выполнение 0 промахов L2C; 0 наносекунд, потраченных на выполнение 0 сбросов (сброс всего 0 объектов)и 0 коллекций); 0 наносекунд, потраченных на выполнение 0 частичных сбросов (сброс всего 0 сущностей и 0 коллекций)
Создание соединения JDBC требует времени даже при использовании пула соединений Hikari. Хикарисвойства
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?