https://blog.csdn.net/blueheart20/article/details/21019043

https://blog.csdn.net/yerenyuan_pku/article/details/70768603

引言:  Hibernate是目前Java领域事实上的ORM实现标准,它以优雅的方式解决了面向对象和面向Table之间的不匹配状态,是解决Java应用中数据持久化的框架。由于Hibernate自行管理从数据库中读入的数据,则容易出现内存占用过大的问题,那如何来解决这个问题或者降低这种问题出现的概率呢?本文将尝试把其中的若干策略进行总结。

1. 尽可能不用或者少用多对多,将其拆分为,一对多和多对一。

2.  根据程序中实际的需求,选择性加载表中的数据,除非必须,一般无需加载全部字段。

3.  在Hibernate中进行查询之时,使用分页降低,一次性的内存负载。

4.  在性能关键的地方,可以尝试使用经过优化的原生SQL,而非HQL

5.  主配置参数(日志,查询缓存,fetch_depth/fetch_size, batch_size等), 优化fetch_size/batch_size大小

大量写入日志,会产生巨大的IO操作,所以可以提高日志级别降低日志的写入量,亦或通过缓存批量的写入。

6.  延迟加载策略的使用,二级缓存的优化,关联表的优化。

7.  事务是数据库操作中非常影响性能的机制,在Hibernate操作中,只保留必须的Update/Delete/Insert的强制事务一致性

另外,排它锁/悲观锁,事务效率低但安全。基于Version字段的乐观锁,则反之。针对不同的数据库应用需要进行平衡,选取适当的平衡点。

8.  完成同样一件事,HIBERNATE提供了可供选择的一些方式,但具体使用什么方式,可能用性能/代码都会有影响。显示,一次返回十万条记录 (List/Set/Bag/Map等)进行处理,很可能导致内存不够的问题,而如果用基于游标(ScrollableResults)或 Iterator的结果集,则不存在这样的问题。

9.   Hibernate vs MyBatis

Hibernate倾向于细颗粒度设计,面向对象,将大表拆分为多个小表,消除冗余字段,通过二级缓存提升性能。
  iBatis倾向于粗颗粒度设计,面向关系,尽量把表合并,通过Column冗余,消除关联关系,但是iBatis没有有效的缓存手段。

10. 选择确当的查询方法

Hibernatne 查询分为两类:一类是得到单个对象,get()和load方法;另一类是得到结果集,list()和iterator()方法。

get()方法和load()方法的区别在于对二级缓存的使用上。load()方法会使用二级缓存,而get()方法在一级缓存没有找到的情况下会直接查询数据库,不会去二级缓存中查找。在使用中,对使用了二级缓存的对象进行查询时最好使用load()方法,以充分利用二级缓存来提高检索的效率。

list()方法和iterator()方法之间的区别可以从以下几个方面来进行比较。

a、  执行的查询不同

list()方法在执行时,是直接运行查询结果所需要的查询语句,而iterator()方法则是先执行得到对象ID的查询,然后再根据每个ID值去取得所要查询的对象。因此,对于list()方式的查询通常只会执行一个SQL语句,而对于iterator()方法的查询则可能需要执行N+1条SQL语句(N为结果集中的记录数)。

iterator()方法只是可能执行N+1条数据,具体执行SQL语句的数量取决于缓存的情况以及对结果集的访问情况。

b、  缓存的使用

list()方法只能使用二级缓存中的查询缓存,而无法使用二级缓存对单个对象的缓存(但是会把查询出的对象放入二级缓存中)。所以,除非重复执行相同的查询操作,否则无法利用缓存的机制来提高查询的效率。

iterator()方法则可以充分利用二级缓存,在根据ID检索对象的时候会首先到缓存中查找,只有在找不到的情况下才会执行相应的查询语句。所以,缓存中对象的存在与否会影响到SQL语句的执行数量。

c、  对于结果集的处理方法不同

list()方法会一次获得所有的结果集对象,而且它会依据查询的结果初始化所有的结果集对象。这在结果集非常大的时候必然会占据非常多的内存,甚至会造成内存溢出情况的发生。

iterator()方法在执行时不会一次初始化所有的对象,而是根据对结果集的访问情况来初始化对象。因此在访问中可以控制缓存中对象的数量,以避免占用过多缓存,导致内存溢出情况的发生。使用iterator()方法的另外一个好处是,如果只需要结果集中的部分记录,那么没有被用到的结果对象根本不会被初始化。所以,对结果集的访问情况也是调用iterator()方法时执行数据库SQL语句多少的一个因素。

所以,在使用Query对象执行数据查询时应该从以上几个方面去考虑使用何种方法来执行数据库的查询操作。

数据库优化:

1.  降低Table之间关联的复杂度,适当进行数据的冗余,提高性能。

2.  减少多级关联的使用

3. 推荐使用lazy加载

这里只是单纯地从hibernate本身出发来介绍如何优化应用,其实从实际优化和性能提升的角度,我们关注的范围远不止此,更多地还是要从系统的维度和业务维度来进行系统优化和提升。

Hibernate优化策略的更多相关文章

  1. Hibernate查询以及优化策略04

    一. HQL查询 1. HQL(hibernate query language)单表查询 1.1 准备项目 创建项目: hinernate-03-query 引入jar,同前一个项目 复制实体(订单 ...

  2. Hibernate —— 检索策略

    一.Hibernate 的检索策略本质上是为了优化 Hibernate 性能. 二.Hibernate 检索策略包括类级别的检索策略.和关联级别的检索策略(<set> 元素) 三.类级别的 ...

  3. Hibernate优化

    前言 在一般情况下,Hibernate需要将执行转换为SQL语句从而性能低于JDBC.但是在经过比较好的性能优化之后,性能还是让人相当满意的,特别是应用二级缓存之后,甚至可以获得比较不使用缓存的JDB ...

  4. 三大框架 之 Hibernate生成策略与缓存策略(主键生成策略、持久化、持久化类划分、一级缓存、事物管理)

    目录 Hibernate生成策略与缓存策略 主键生成策略 主键分类 主键的生成策略 持久化 什么是持久化 什么是持久化类 持久化类编写规则 持久化类的划分 三种状态区分 持久态对象特征 一级缓存 什么 ...

  5. Hibernate 生成策略和缓存策略

    主键生成策略 一.主键分类 1. 自然主键 主键本身就是表中的一个字段,实体中一个具体的属性,对象本身唯一的特性 比如:创建一个学生表:姓名.年龄.身份证号(自然主键) 2. 代理主键 主键本身不是表 ...

  6. 直播推流端弱网优化策略 | 直播 SDK 性能优化实践

    弱网优化的场景 网络直播行业经过一年多的快速发展,衍生出了各种各样的玩法.最早的网络直播是主播坐在 PC 前,安装好专业的直播设备(如摄像头和麦克风),然后才能开始直播.后来随着手机性能的提升和直播技 ...

  7. PHP中的数据库一、MySQL优化策略综述

    前些天看到一篇文章说到PHP的瓶颈很多情况下不在PHP自身,而在于数据库.我们都知道,PHP开发中,数据的增删改查是核心.为了提升PHP的运行效率,程序员不光需要写出逻辑清晰,效率很高的代码,还要能对 ...

  8. .Net中的并行编程-6.常用优化策略

                本文是.Net中的并行编程第六篇,今天就介绍一些我在实际项目中的一些常用优化策略.      一.避免线程之间共享数据 避免线程之间共享数据主要是因为锁的问题,无论什么粒度的锁 ...

  9. Spark SQL概念学习系列之Spark SQL 优化策略(五)

    查询优化是传统数据库中最为重要的一环,这项技术在传统数据库中已经很成熟.除了查询优化, Spark SQL 在存储上也进行了优化,从以下几点查看 Spark SQL 的一些优化策略. (1)内存列式存 ...

随机推荐

  1. Linux系统对IO端口和IO内存的管理

    引用:http://blog.csdn.net/ce123_zhouwei/article/details/7204458 一.I/O端口 端口(port)是接口电路中能被CPU直接访问的寄存器的地址 ...

  2. 20145118《Java程序设计》 第7周学习总结

    20145118<Java程序设计> 第7周学习总结 教材学习内容总结 本周学习内容为第十三章,以下为教材内容重点总结: 1.格林威治标准时间简称GMT时间. 2.java.util.Da ...

  3. 探索Java8:(二)Function接口的使用

    Java8 添加了一个新的特性Function,顾名思义这一定是一个函数式的操作.我们知道Java8的最大特性就是函数式接口.所有标注了@FunctionalInterface注解的接口都是函数式接口 ...

  4. Python3基础 setattr 设置对象的属性值,如果属性不存在就创建

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  5. 格子中输出|2015年蓝桥杯B组题解析第四题-fishers

    StringInGrid函数会在一个指定大小的格子中打印指定的字符串. 要求字符串在水平.垂直两个方向上都居中. 如果字符串太长,就截断. 如果不能恰好居中,可以稍稍偏左或者偏上一点. 下面的程序实现 ...

  6. 【第二十六章】 hystrix-dashboard + turbine

    一.使用turbine的意义 引入多个hystrix stream: 1.使用hystrix-dashboard的可以添加多个stream的功能 图中添加的两个stream会在真正monitor的时候 ...

  7. 51nod 1428 活动安排问题 (贪心+优先队列)

    来源:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1428 首先按照开始时间从小到大排序. 其实只要维护一个结束时间的最 ...

  8. Java8的新特性,二进制序列转十进制数字

    package kata_007_二进制序列转十进制int; /** * java8 Lambda表达式转换binary序列->十进制数 */ import java.util.ArrayLis ...

  9. 利用Ajax和Servlet实现输入框提示功能

    目的和效果:     输入框输入字符串x,匹配后台传入的数据str,如果str中的元素包含字符串x,则提示. 后台代码:                   String x = request.ge ...

  10. OpenVirteX 创建简易虚拟网络

    OpenVirteX 创建简易虚拟网络 1.打开OVX sh OpenVirteX/script/ovx.sh 2.创建mininet物理拓扑 1sw, 2hosts mn --controller= ...