Советы по настройке производительности гибернации

Я разрабатываю небольшое приложение, состоящее из одной таблицы.

Я использую следующие технологии: NetBeans 8.1 Java 8 Hibernate 4.3.x Informix Primefaces 5

Мне пришлось исследовать время, чтобы подключиться к Informix Hibernate, но я его получил, и приложение правильно отображает список с запрошенными данными.

Проблема возникает с производительностью Hibernate, которая очень плохая, особенно учитывая, что таблица содержит всего 36000 записей.

На каждую смену страницы уходит около 6-7 секунд.

Я изучал официальную документацию Hibernate, но не могу найти конкретных примеров повышения производительности.

При этом код приложения:

спящий режим.cfg.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
   <property name="hibernate.dialect">org.hibernate.dialect.InformixDialect</property>
   <property name="hibernate.connection.driver_class">com.informix.jdbc.IfxDriver</property>
   <property name="hibernate.connection.url">jdbc:informix-sqli://127.0.0.1:1526/chicho:INFORMIXSERVER=ol_chicho</property>
   <!--<property name="hibernate.connection.datasource">jdbc/votacion</property>-->
   <property name="hibernate.connection.username">informix</property>
   <property name="hibernate.connection.password">informix</property>
   <property name="hibernate.connection.autocommit">true</property>
   <property name="hibernate.current_session_context_class">thread</property>
   <property name="hibernate.default_schema">informix</property>
   <property name="hibernate.show_sql">true</property>
   <property name="hibernate.hbm2ddl.auto">validate</property>
   <property name="hibernate.cache.use_second_level_cache">true</property>
   <mapping resource="pojos/Xxpuedenvotar1.hbm.xml"/>
 </session-factory>

Pojo:

package pojos;
// Generated 23/08/2016 22:07:42 by Hibernate Tools 4.3.1



/**
 * Xxpuedenvotar1 generated by hbm2java
 */
public class Xxpuedenvotar1  implements java.io.Serializable {


 private Integer nroaccionista;
 private Short estado;
 private Integer idcliente;
 private String razonSocial;
 private Short idlocalidad;
 private Short zona;
 private String calle;
 private String puerta;
 private String localidad;

public Xxpuedenvotar1() {
}


public Xxpuedenvotar1(Integer nroaccionista) {
    this.nroaccionista = nroaccionista;
}
public Xxpuedenvotar1(Integer nroaccionista, Short estado, Integer idcliente, String razonSocial, Short idlocalidad, Short zona, String calle, String puerta, String localidad) {
   this.nroaccionista = nroaccionista;
   this.estado = estado;
   this.idcliente = idcliente;
   this.razonSocial = razonSocial;
   this.idlocalidad = idlocalidad;
   this.zona = zona;
   this.calle = calle;
   this.puerta = puerta;
   this.localidad = localidad;
}

public Integer getNroaccionista() {
    return this.nroaccionista;
}

public void setNroaccionista(Integer nroaccionista) {
    this.nroaccionista = nroaccionista;
}
public Short getEstado() {
    return this.estado;
}

public void setEstado(Short estado) {
    this.estado = estado;
}
public Integer getIdcliente() {
    return this.idcliente;
}

public void setIdcliente(Integer idcliente) {
    this.idcliente = idcliente;
}
public String getRazonSocial() {
    return this.razonSocial;
}

public void setRazonSocial(String razonSocial) {
    this.razonSocial = razonSocial;
}
public Short getIdlocalidad() {
    return this.idlocalidad;
}

public void setIdlocalidad(Short idlocalidad) {
    this.idlocalidad = idlocalidad;
}
public Short getZona() {
    return this.zona;
}

public void setZona(Short zona) {
    this.zona = zona;
}
public String getCalle() {
    return this.calle;
}

public void setCalle(String calle) {
    this.calle = calle;
}
public String getPuerta() {
    return this.puerta;
}

public void setPuerta(String puerta) {
    this.puerta = puerta;
}
public String getLocalidad() {
    return this.localidad;
}

public void setLocalidad(String localidad) {
    this.localidad = localidad;
}
}

ДАО:

package Dao;

import Interfaces.InterfazSocios;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import pojos.Xxpuedenvotar1;

/**
 *
 * @author Gustavo
*/
public class DaoSocios implements InterfazSocios {

private List<Xxpuedenvotar1> listaSocios;

@Override
public List<Xxpuedenvotar1> verTodos(Session sesion) throws Exception {
    String hql = "FROM Xxpuedenvotar1 ORDER BY NroAccionista";
    //Query consulta = sesion.createQuery(hql).setCacheable(true);
    this.listaSocios = sesion.createCriteria(Xxpuedenvotar1.class).list();
    //this.listaSocios = consulta.list();
    return this.listaSocios;
}

}

Думаю с этими файлами достаточно для анализа, так как приложение работает хорошо, за исключением своей медлительности.

Заранее благодарим за внимание.


person Gustavo Echenique    schedule 08.09.2016    source источник
comment
Я вижу, что вы включили журнал SQL в конфигурации гибернации. Что происходит, когда вы запускаете сгенерированный запрос на своей таблице? Вы все еще находите медлительность? У вас есть лучший запрос, который вы можете использовать вместо HQL?   -  person Ramachandran.A.G    schedule 08.09.2016
comment
если порядок по полю не индексируется, это может стать очень медленным   -  person holtc    schedule 08.09.2016
comment
Пахнет индексацией. Опубликуйте таблицу DDL.   -  person chrylis -cautiouslyoptimistic-    schedule 08.09.2016
comment
@Ramachandran, если я запускаю SQL-запрос вне Hibernate, результат отображается мгновенно, это действительно очень быстро. У меня нет лучшего запроса, так как он очень простой (попросите создать базу для всех записей). Вот что меня удивляет, потому что, если я делаю это с шаблонами JSF, неиспользуемыми Primefaces, пейджинг работает отлично.   -  person Gustavo Echenique    schedule 09.09.2016


Ответы (2)


Можно попробовать любой из них или все из них в зависимости от конфигурации, доступности изменения свойств конфигурации.

  • hibernate.show_sql пометьте это значение как false, как только вы закончите анализ формирования запроса. Это требует времени для регистрации.
  • Вы можете изменить конфигурацию размера пула соединений, если вы его используете.
  <property name="hibernate.c3p0.min_size">5</property>
  <property name="hibernate.c3p0.max_size">20</property>

Это помогает быстро установить соединение из пула. Избегает времени, чтобы получить соединение.

  • Если у вас большие данные, отметьте соответствующий столбец в классе JPA знаком @OrderBy.

  • Поиск в спящем режиме предоставляет @SortableField для аннотирования поля. Это внутренне индексирует и помогает получить отсортированные результаты.

[РЕДАКТИРОВАТЬ]

Если Integer nroaccionista является первичным ключом, он индексируется по умолчанию. Отметьте столбец в классе JPA с помощью @Id и оператора создания DDL, сгенерированного с созданием индекса по умолчанию. Индексированный столбец помогает лучше искать и сортировать результаты.

Надеюсь это поможет.

person VinayVeluri    schedule 08.09.2016
comment
Я пытался создать пул соединений с C3P0 с параметрами, которые вы мне передали в своем посте, я также создал соединение через JNDI для Glassfish, но результаты те же. Столбец NroAccionista является PK, поэтому он индексируется. Не могу понять где проблема. - person Gustavo Echenique; 09.09.2016
comment
@ user3624506, если сервер является вашим локальным хостом, откройте JVisualVM и подключитесь к локальному серверу и проанализируйте дамп потока, где стек вызовов занимает больше памяти и времени обработки. Это дает вам полное представление о том, как вы можете уменьшить сложность времени и пространства. - person VinayVeluri; 09.09.2016

Прежде всего, есть много вещей, которые вы можете сделать, чтобы ускорить Hibernate. Ознакомьтесь с этими советами по высокопроизводительному спящему режиму или с этим Высокопроизводительная видеопрезентация Hibernate.

Теперь вернемся к вашему вопросу. Вы используете DriverManagerConnectionProvider, который предоставляет только элементарное решение для пула соединений. Лучше использовать HikariCP, так как он самый быстрый, а также доступен через hibernate-hikaricp. Зависимость от Мавена.

В связи с вашим заявлением:

Проблема возникает с производительностью Hibernate, которая очень плохая, особенно учитывая, что таблица содержит всего 36000 записей.

На каждую смену страницы уходит около 6-7 секунд.

Почему вы хотите получить 36 тысяч записей за один раз?

Вы не можете отобразить их в пользовательском интерфейсе? Вот почему у нас есть пагинация данных.

Даже для пакетного процессора лучше разделить всю рабочую нагрузку на несколько меньших наборов данных, что позволит избежать длительных транзакций и даже разделить нагрузку между несколькими рабочими потоками.

person Vlad Mihalcea    schedule 09.09.2016