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 性能调优技巧的主要内容,如果未能解决你的问题,请参考以下文章