锁定老帖子 主题:发疯Hibernate分页问题,性能优化!
精华帖 (2) :: 良好帖 (0) :: 新手帖 (18) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-07-25
最后修改:2009-02-07
最近写了一个Hibernate分页,之前用游标来实现得到count 总行数..用HQL语句查询!可是现在问题出现了,但数据达到海量的时候,出现比较慢,现在要进行优化: 1.不能使用游标得到count总行数! ScrollableResults rs = query.scroll(ScrollMode.SCROLL_INSENSITIVE); 2.不能使用select count(*) from .....这样要得到count 和list 分布操作很麻烦!查询和count 都要同步!不想两次操作... 假如更改字段都要更改...不想这么做!要公用.... 3.不能使用query.list().size() int count=query.list().size(); 除了这三种方法实现得到count,不知道还能用什么方法去实现!相信javaeye上面大师们应该会出现这样情况吧!遇到过的提提建议... 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-07-25
是分页有性能问题,还是取总记录数有性能问题?有没有试过用Query的setFirstResult和setMaxResults方法来实现分页?
|
|
返回顶楼 | |
发表时间:2008-07-25
movingboy 27 分钟前
是分页有性能问题,还是取总记录数有性能问题?有没有试过用Query的setFirstResult和setMaxResults方法来实现分页? 是取总记录数有性能问题哈?我就是用Query的setFirstResult和setMaxResults方法来实现分页?又没什么好方法来实现得到count总记录数! 谢谢! |
|
返回顶楼 | |
发表时间:2008-07-25
myprincejava 写道 movingboy 27 分钟前
是分页有性能问题,还是取总记录数有性能问题?有没有试过用Query的setFirstResult和setMaxResults方法来实现分页? 是取总记录数有性能问题哈?我就是用Query的setFirstResult和setMaxResults方法来实现分页?又没什么好方法来实现得到count总记录数! 谢谢! |
|
返回顶楼 | |
发表时间:2008-07-25
lz用的什么数据库?又是什么驱动?
看看http://www.iteye.com/topic/9881?page=1 除了count(*),还可以用服务器端游标的,不过跟数据库驱动实现有关 |
|
返回顶楼 | |
发表时间:2008-07-25
建议总数可以缓存一下
|
|
返回顶楼 | |
发表时间:2008-07-25
如果是动态查询,总数是变动的,无法缓存。
暂无办法,唯有数据库 performance tuning or query tuning。 |
|
返回顶楼 | |
发表时间:2008-07-25
我觉得老老实实用select count(*) from ...就好了,但你已经说不能这样用,我就没办法了
|
|
返回顶楼 | |
发表时间:2008-07-25
只有第二种方法最现实,然后继续缓存优化,缓存时间可以缩小到5秒级的,可解决并发问题,5秒延时大多数状态下都是能够接受的。
第二种的HQL的通用实现,请参考SpringSide2的源代码。 org.springside.core.dao.HibernateGenericDao /**分页查询函数,使用hql * @param hql String * @param values Object[] * @param pageParam 页面查询参数 * @param alias 排序表的别名,排序的时候才起作用 * @return Page(totalProperty, list) */ public Page findPage(String hql, Object[] values, PageParam pageParam, String alias) { Assert.hasText(hql); Assert.notNull(pageParam); if (values == null) { values = new Object[] {}; } // Count查询 String countQueryString = "SELECT COUNT(*) " + HqlUtils.removeSelect(HqlUtils.removeOrders(hql)); long totalCount = ((Long) getHibernateTemplate().find(countQueryString, values) .get(0)).longValue(); if (StringUtils.isNotEmpty(pageParam.getSort())) { Assert.hasText(alias); hql = HqlUtils.removeOrders(hql); hql += " ORDER BY " + alias + "." + pageParam.getSort(); if (pageParam.getDir().equals(PageParam.DIR_ASC)) { hql += " ASC"; } else { hql += " DESC"; } } // 实际查询返回分页对象 Query query = createQuery(hql, values); query.setFirstResult(pageParam.getStart()); query.setMaxResults(pageParam.getLimit()); List list = query.list(); return new Page((int) totalCount, list); } |
|
返回顶楼 | |
发表时间:2008-07-25
同时提醒,楼主的第一和第三种方法几乎是无法用在生产环境的,性能太差了,是绝对要避免出现的。
除非记录数在100以下,但是一般都会使用通用接口,所以即使适用小数据量也是没有太大的实际开发意义。 |
|
返回顶楼 | |