2008-07-25
发疯Hibernate分页问题,性能优化!
最近写了一个Hibernate分页,之前用游标来实现得到count 总行数..用HQL语句查询!可是现在问题出现了,但数据达到海量的时候,出现比较慢,现在要进行优化:
1.不能使用游标得到count总行数!
ScrollableResults rs = query.scroll(ScrollMode.SCROLL_INSENSITIVE);
rs.last();
return (rs.getRowNumber() + 1);
2.不能使用select count(*) from .....这样要得到count 和list 分布操作很麻烦!查询和count 都要同步!不想两次操作...
假如更改字段都要更改...不想这么做!要公用....
3.不能使用query.list().size()
int count=query.list().size();
除了这三种方法实现得到count,不知道还能用什么方法去实现!相信javaeye上面大师们应该会出现这样情况吧!遇到过的提提建议...
评论
soci
8 小时前
这样行不:
hql作为分页类的参数,方法签名:
listByPage(String hql,Page page)
int position = hql.toLowerCase().indexOf("from");
String totalHql = "select count(*) as totals " + hql.substring(position);
这个就可以算总数了,ORDER BY 其实不去掉也没事吧。
hql作为分页类的参数,方法签名:
listByPage(String hql,Page page)
int position = hql.toLowerCase().indexOf("from");
String totalHql = "select count(*) as totals " + hql.substring(position);
这个就可以算总数了,ORDER BY 其实不去掉也没事吧。
iamzealotwang
10 小时前
/**
* 去除hql的select 子句
* @param hql
* @return hql
*/
public static String removeSelect(String hql) {
Assert.hasText(hql);
int beginPos = hql.toLowerCase().indexOf("from");
Assert.isTrue(beginPos != -1, " hql : " + hql + " must has a keyword 'from'");
return hql.substring(beginPos);
}
/**
* 去除hql的orderby 子句
* @param hql
* @return hql
*/
public static String removeOrders(String hql) {
Assert.hasText(hql);
Pattern pattern = Pattern.compile("order\\s*by[\\w|\\W|\\s|\\S]*"
, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(hql);
StringBuffer buf = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(buf, "");
}
matcher.appendTail(buf);
return buf.toString();
}
其中这个removeOrders 和 removeSelect 谁能告诉我一下有什么用处么? 谢谢
还有关于这种海量数据分页的问题,如果不是很在意总数的实事性,是否可以只在第一次查询的时候就算出count,后面的查询只查询内容而不用再次计算count呢?
即第一次查询:
1·查处满足sql条件的所有记录数目 ( count(*) )
2·返回前100条数据
第二次查询(即表示层调用了翻页)
1·查询满足sql条件的第101~200条记录
.....
第n次查询(查找到最后一页)
1·查询满足sql条件的第1000~1200条记录(假设count*的结果是1200)
请问是这样一个过程么 ? 谢谢
litianyi520
12 小时前
不行就用lucence 吧~ 索引文件搞~ 查库啥时候都慢~
lu_pp
13 小时前
caohj 写道
建议用一个字段来存储count数,当有增加一条记录时count数+1,删除对应的一条记录时,count -1,查询分页的取count数时候直接去取一个字段记录就可以了.
按不同条件进行查询的话,好象就不好用了
我是使用SELECT COUNT 来返回总数
。。。
13 小时前
放一个List getPage(int page)的方法出来,如果返回的list是empty的, 给用户弹个对话框就说找不着了。至于跳转....提供首尾页和上下翻的按钮, 再提供一个页码输入框......大不了我不告诉你到底有多少记录.....
一定要计算Count的话,尽量避免count(*)的出现。
不过我实际环境中还没用过这种方法. 只是一个想法。
计算Count数据库可能有点小负担,而且还是count(*)。
一定要计算Count的话,尽量避免count(*)的出现。
不过我实际环境中还没用过这种方法. 只是一个想法。
计算Count数据库可能有点小负担,而且还是count(*)。
我不知道
2008-08-07
4300万的数据 用户不可能查出这么多的数据,1页1页的翻着看吧。
我要是用户我准是疯了。
可能给用户分页100页,每页100条(那就是100×100=10000条),就已经疯了。当然,有时候他想知道总数,那就给他提供一个可查看总数的地方。不过我认为,分页这里没有几个用户分了100页,1页1页看的。
所以可以考虑在查询条件方面限制用户查出那么多的数据,比如用户必须选择某个查询条件等。
而且,只在第1次访问的时候计算总数,其他翻页的时候把总数和分页数等传过去好了。
我要是用户我准是疯了。
可能给用户分页100页,每页100条(那就是100×100=10000条),就已经疯了。当然,有时候他想知道总数,那就给他提供一个可查看总数的地方。不过我认为,分页这里没有几个用户分了100页,1页1页看的。
所以可以考虑在查询条件方面限制用户查出那么多的数据,比如用户必须选择某个查询条件等。
而且,只在第1次访问的时候计算总数,其他翻页的时候把总数和分页数等传过去好了。
icewubin
2008-08-04
池中物 写道
Criteria criteria = session.createCriteria(Blog.class);
return criteria.setProjection(Projections.rowCount()).uniqueResult();
return criteria.setProjection(Projections.rowCount()).uniqueResult();
这个就是select count(*)
池中物
2008-08-04
Criteria criteria = session.createCriteria(Blog.class);
return criteria.setProjection(Projections.rowCount()).uniqueResult();
return criteria.setProjection(Projections.rowCount()).uniqueResult();
neptune
2008-08-04
select count(*) 还能再优化吗?,还是把最常用的分页,第一页count(*)后结果和列表结果,缓存的好。第一页是最常用的了。
jy02411368
2008-08-03
我现在用的是displaytag经过优化了。。其实也不错 而且代码量很少
icewubin
2008-08-02
smilerain 写道
可以参考论坛的实现方法,做一个cache保存总数。添加就+1,删除就-1.
时不时的修正一下数据就可以了。
时不时的修正一下数据就可以了。
查询多半是带条件的,结果往往不是缓存的总数。
论坛的这种缓存策略只适合特定需求的。
smilerain
2008-08-02
可以参考论坛的实现方法,做一个cache保存总数。添加就+1,删除就-1.
时不时的修正一下数据就可以了。
时不时的修正一下数据就可以了。
corelengine
2008-08-01
查询结果写到session里用display tag
mingli1223
2008-08-01
根据业务来.数据量小,就count(*),量大就改策略如提前缓存.
burt
2008-08-01
ecsun 写道
count(*)一般来说会损失一些性能,加上first和max以后,基本可以不考虑损失的性能,如果实在能count(*)性能不满意
或以改为count(id),这种方式比count(*)性能要好一些
可以拿你的海量数据测一下,就明白了.
同时,如果真的数据量太海量了,count也就意义不大了.这时候可以这么做,比如每一次取出1000条记录,放前台去分页,当然,是不是一次1000条,要看你的访问压力了.
因为频繁访问海量数据,本身对数据库已经是一个很大的压力了,为了每次取得10条一页的数据,去访问一次数据库,划不来,一次多取一点,展现完了再去后台取.
或以改为count(id),这种方式比count(*)性能要好一些
可以拿你的海量数据测一下,就明白了.
同时,如果真的数据量太海量了,count也就意义不大了.这时候可以这么做,比如每一次取出1000条记录,放前台去分页,当然,是不是一次1000条,要看你的访问压力了.
因为频繁访问海量数据,本身对数据库已经是一个很大的压力了,为了每次取得10条一页的数据,去访问一次数据库,划不来,一次多取一点,展现完了再去后台取.
用mssql,4300万的数据,相比select count(*),select count(id)并没有多大提升。
还是4分钟36秒左右。
jackey3316
2008-07-31
count(*) 有性能问题? 优化数据库看看~~
liubat365
2008-07-31
mysql数据库里面select count(*)时不能在条件里面加子查询,否则速度超级慢。
icewubin
2008-07-31
bhan2008 写道
select count(1) from ..... 应该会好一点吧
在Oracle下,count(1)和count(*)同样高效,其他数据库的效率不清楚,只要数据库优化,可能是也是一样的。
参考自
http://www.itpub.net/viewthread.php?tid=592976&extra=&page=3
bhan2008
2008-07-30
select count(1) from ..... 应该会好一点吧
davidcen
2008-07-29
第一次检索都要计算count值,传到页面做缓存;
from 表 发生变化,如join不同的表 也要重新计算count;
from表或者多表有增删操作,使用aop通知Pager重新计算count;
from 表 发生变化,如join不同的表 也要重新计算count;
from表或者多表有增删操作,使用aop通知Pager重新计算count;
发表评论
提醒: 该博客已发表在公共论坛,博客所有留言会成为论坛回贴,留言请注意遵守论坛发贴规则
- 浏览: 656 次
- 性别:

- 来自: 珠海

- 详细资料
搜索本博客
最近加入圈子
最新评论
-
发疯Hibernate分页问题, ...
这样行不: hql作为分页类的参数,方法签名: listByPage(Strin ...
-- by soci -
发疯Hibernate分页问题, ...
/** * 去除hql的select 子句 ...
-- by iamzealotwang -
发疯Hibernate分页问题, ...
不行就用lucence 吧~ 索引文件搞~ 查库啥时候都慢~
-- by litianyi520 -
发疯Hibernate分页问题, ...
caohj 写道建议用一个字段来存储count数,当有增加一条记录时count数 ...
-- by lu_pp -
发疯Hibernate分页问题, ...
放一个List getPage(int page)的方法出来,如果返回的list ...
-- by 。。。






评论排行榜