两种极端:频繁的查询和巨大的结果集
2010-05-09 11:16
176 查看
写到这篇文章时,我们可以对Hibernate的性能调优策略做一个宏观的剖析了。当系统访问一个实体时,Hibernate会到数据库中提取相应数据封装成实体供程序使用,但大多数情况下问题并不是这样简单。对象模型由很多实体和值对象组成,它们之间相互依赖,构成一张复杂的“对象图”。从一个指定的对象开始,我们可以导航到与这个对象有直接或间接关系的任何对象上。再回到我们一开始的问题:你怎样从数据库中重建这个对象?我们很容易想到两种基本的策略:
策略1:开始时只加载这个对象的基本数据。当要从这个对象导航到其他对象时,再将目标对象从数据库中加载出来。这就是hibernate中的lazy loading.这个策略可以避免一次性载入过多数据,代价却是需要频繁访问数据库。这就是“过多查询”的问题。这种情况典型的例子是N+1次查询问题(参考JPwH13.2.5)。
策略2:一开始就将该对象和它的所有并联对象一次性查出。这就是hibernate中的eager fetch.这个策略消除了频繁访问数据库的问题,但它会加载太多的数据。它的查询结果是一个巨大的笛卡尔积!(至于为什么是笛卡尔积请参考http://blog.csdn.net/bluishglc/archive/2010/05/09/5571403.aspx,简单说:当这个对象有两个以上的关联集合时,查询结果就必然是一个笛卡尔积了)并且可能很多数据我们都不会用到。笛卡尔积问题同样参考JPwH13.2.5。
在这两种基本策略,也是两种极端的情况下:我们通过Hibernate进行的性能调优无非就是要在这两者之间取得一个平衡:使用最少的查询得到必需的数据,不加载本次用例(use case)使用不到的对象!这就需要我们为每个用例制定hibernate动态抓取策略也可以叫抓取计划来实现!
策略1:开始时只加载这个对象的基本数据。当要从这个对象导航到其他对象时,再将目标对象从数据库中加载出来。这就是hibernate中的lazy loading.这个策略可以避免一次性载入过多数据,代价却是需要频繁访问数据库。这就是“过多查询”的问题。这种情况典型的例子是N+1次查询问题(参考JPwH13.2.5)。
策略2:一开始就将该对象和它的所有并联对象一次性查出。这就是hibernate中的eager fetch.这个策略消除了频繁访问数据库的问题,但它会加载太多的数据。它的查询结果是一个巨大的笛卡尔积!(至于为什么是笛卡尔积请参考http://blog.csdn.net/bluishglc/archive/2010/05/09/5571403.aspx,简单说:当这个对象有两个以上的关联集合时,查询结果就必然是一个笛卡尔积了)并且可能很多数据我们都不会用到。笛卡尔积问题同样参考JPwH13.2.5。
在这两种基本策略,也是两种极端的情况下:我们通过Hibernate进行的性能调优无非就是要在这两者之间取得一个平衡:使用最少的查询得到必需的数据,不加载本次用例(use case)使用不到的对象!这就需要我们为每个用例制定hibernate动态抓取策略也可以叫抓取计划来实现!
相关文章推荐
- Symfony原生sql语句获取查询结果的两种方法
- linq查询结果指定列的两种方式
- 尽量不要用工具频繁去查询排名结果_seo优化禁忌
- **CI两种方式查询所返回的结果数量
- KbmMW两种查询结果集通讯方式
- 两种极端情况的案例:N+1次查询和笛卡尔积
- sqlsever 一表查询两种条件时间并合并查询结果
- 可能导致du与df查询结果不一致的两种场景
- linq查询结果指定列的两种方式
- 在查询结果时,在页面显示等待....的两种方法
- JdbcTemplate查询数据中两种处理结果集方法的简单比较
- 在SQL查询结果中添加自增列的两种方法
- mysql 存储过程 动态参数 查询执行结果
- 如何让SELECT 查询结果额外增加自动递增序号
- 通过SQL查询多个表的结果且分页
- Oracle查询结果自动生成序号
- SQL查询结果的合并问题
- 把查询到结果合并放在一行 JOIN非union
- sql语句查询,分批显示查询结果
- oracle 存储过程 输出结果和正常查询不一样