Hibernate 性能调优技巧

Posted

技术标签:

【中文标题】Hibernate 性能调优技巧【英文标题】:Hibernate performance tuning tips 【发布时间】:2016-09-08 03:37:45 【问题描述】:

我正在开发一个小型应用程序,它由一个表组成。

我使用的技术是: NetBeans 8.1 爪哇 8 休眠 4.3.x Informix Primefaces 5

我不得不调查连接 Informix Hibernate 的时间,但我得到了它,并且应用程序正确显示了包含请求数据的列表。

问题出在Hibernate的性能上,性能很差,特别是考虑到表只包含36000条记录。

每页更改大约需要 6 或 7 秒。

我一直在研究Hibernate的官方文档,但找不到具体的例子来提高性能。

这里附上申请代码:

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>

波乔:

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;



我认为这些文件足以进行分析,因为该应用程序运行良好,但速度较慢。

提前感谢您的关注。

【问题讨论】:

我看到您在休眠配置中启用了 SQL 日志。当您在表上运行生成的查询时会发生什么?你还觉得慢吗?你有更好的查询来代替 HQL 吗? 如果 order by 字段没有被索引,这可能会变得很慢 闻起来像索引。发布表 DDL。 @Ramachandran,如果我在 Hibernate 之外运行 SQL 查询,结果会立即显示出来,确实非常快。我没有更好的查询,因为它非常基本(要求以所有记录为基础)。这让我感到惊讶,因为如果我使用未使用的 Primefaces 的 JSF 模板来做,分页非常好。 【参考方案1】:

可以根据配置、修改配置属性的可用性来尝试这些或所有这些。

hibernate.show_sql 将此标记为 false,一旦您完成对查询形成的分析。这需要时间来记录。 您可以更改连接池大小配置,如果您使用的是一个
  <property name="hibernate.c3p0.min_size">5</property>
  <property name="hibernate.c3p0.max_size">20</property>

这有助于从池中快速获得连接。避免获得连接的时间。

如果您有大量数据,请在 JPA 类中的相应列上标记@OrderBy

Hibernate 搜索提供 @SortableField 来注释字段,这在内部建立索引并有助于检索排序结果。

[编辑]

如果Integer nroaccionista 是主键,则默认索引。用@Id 标记JPA 类中的列,默认情况下使用创建索引生成的DDL 创建语句。索引列有助于更好地搜索和排序结果。

希望这会有所帮助。

【讨论】:

我试图使用您在帖子中传递给我的参数创建一个带有 C3P0 的连接池,我还通过 JNDI 创建了一个到 glassfish 的连接,但结果是一样的。 NroAccionista 的列是 PK,所以它被索引了。我不明白问题出在哪里。 @user3624506,如果服务器是你的本地主机,打开JVisualVM并连接到本地服务器并分析线程转储,因为调用堆栈占用了更多的内存和处理时间。这让您全面了解如何降低时间和空间复杂度。【参考方案2】:

首先,您可以做很多事情来加速 Hibernate。看看这些High-Performance Hibernate Tips,或者这个High-Performance Hibernate video presentation。

现在,回到你的问题。您正在使用DriverManagerConnectionProvider,它仅提供基本的连接池解决方案。最好使用 HikariCP,因为它是最快的,也可以通过 hibernate-hikaricp Maven 依赖项获得。

与你的陈述有关:

问题出在Hibernate的性能上,这非常 很差,特别是考虑到该表只包含 36000 记录。

每页更改大约需要 6 或 7 秒。

为什么要一次获取 36k 条记录?

您不能将它们显示到 UI 中?这就是我们拥有data pagination 的原因。

即使对于批处理器,您最好将整个工作负载拆分为多个较小的数据集,这样您就可以避免长时间运行的事务,甚至可以在多个工作线程之间分配负载。

【讨论】:

以上是关于Hibernate 性能调优技巧的主要内容,如果未能解决你的问题,请参考以下文章

北大青鸟java培训:Java性能调优都有哪些技巧?

MySQL 性能调优和优化技巧

重剑无锋 | Hive性能调优

iOS-------应用性能调优的25个建议和技巧

Spark+Alluxio性能调优十大技巧

11 个简单的 Java 性能调优技巧