|
精华帖 (0) :: 良好帖 (0) :: 新手帖 (17) :: 隐藏帖 (0)
|
|
|---|---|
| 作者 | 正文 |
|
时间:2008-07-25
最近写了一个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上面大师们应该会出现这样情况吧!遇到过的提提建议... 声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
时间: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.javaeye.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以下,但是一般都会使用通用接口,所以即使适用小数据量也是没有太大的实际开发意义。 |
|
| 返回顶楼 | |






