hibernate已实现分页查询,数据量百万以上越往后的数据查询的越慢,怎么解决?

sw4433 2010-01-20 09:03:11
hibernate已实现分页查询,查询前面的数据速度很快,但查询后面的数据就很慢:

比如我现在是 200,0000 条记录,
页面 是: 首页 上一页 下一页 尾页

点首页或点下一页查询很快,但点尾页就要十几秒才能查询到,此时再点上一页也是需要十几秒才能查询到

也就是说越往后的数据查询的越慢,有什么好的办法能解决此问题?

有没有比较好的方法能显著提升速度?
...全文
2053 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhishouzhetian88 2010-09-27
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 ginger1024 的回复:]
数据优化一直是难题, 学习....
[/Quote]


学习中...
sunnylyy 2010-01-21
  • 打赏
  • 举报
回复
跟一次查多少条关系不大,界面上强制加查询条件吧,然后用到索引。比如name字段建立索引,查询的时候类似这样:from GuestBook where name like 'AAA%'

order by尽量不要加了。

其实想想,对一个几百万的大表做分页显示,还不加任何查询条件,好象没什么必要。
sw4433 2010-01-21
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 sunnylyy 的回复:]
想用到id这个索引,sql语句要类似这样: select * from GuestBook where id = ?

select * from GuestBook这样是用不到的。

另外"from GuestBook order by id asc"这句得优化,把order by id asc去掉,id是主键,本身就是排好序的了
[/Quote]

sql语句我知道,如果是通过别的字段排序,怎么提高效率呢?比如通过name查询,by name desc
query.setFirstResult(firstResult).setMaxResults(maxResult);
这是设置从哪条数据查,一次查询多少条数据
sunnylyy 2010-01-21
  • 打赏
  • 举报
回复
想用到id这个索引,sql语句要类似这样: select * from GuestBook where id = ?

select * from GuestBook这样是用不到的。

另外"from GuestBook order by id asc"这句得优化,把order by id asc去掉,id是主键,本身就是排好序的了
sw4433 2010-01-21
  • 打赏
  • 举报
回复
	//查找记录
public List getAllGuestBooks(int firstResult,int maxResult){
Session session = this.getSession();
System.out.println("all");
List list = null;;
try {
Query query = session.createQuery("from GuestBook order by id asc");
query.setFirstResult(firstResult).setMaxResults(maxResult);
list = query.list();
} catch (HibernateException e) {
e.printStackTrace();
} finally{
session.close();
}
return list;
}

id为主键,我是传的是参数啊query.setFirstResult(firstResult).setMaxResults(maxResult);
sunnylyy 2010-01-21
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 sw4433 的回复:]
Java codeHibernate: select top10 guestbook0_.id as id0_, guestbook0_.name as name0_, gue
stbook0_.email as email0_, guestbook0_.url as url0_, guestbook0_.title as title0
_, guestbook0_.context as context0_, guestbook0_.time as time0_ from guestBook.d
bo.guestBook guestbook0_ order by guestbook0_.id asc


[/Quote]

这么写,where条件也没有,建了索引也用不到,每次运行都是从表的起始位置开始一行行扫描,当然越往后越慢了。
BearKin 2010-01-21
  • 打赏
  • 举报
回复
曾经看过一个人问SQL SERVER 2000如何去除伪分页 我才知道 HIBERNATE在SQL SERVER 2000里用的是伪分页 后来SQLSERVER 2005有类似Oracle的分页函数了之后 就可以通过修改数据库方言 让HIBERNATE支持真分页了

http://blog.csdn.net/tdl982324/archive/2008/07/03/2607674.aspx

LZ看这个
fengzhishang55 2010-01-21
  • 打赏
  • 举报
回复
学习中..
autocomplete 2010-01-21
  • 打赏
  • 举报
回复
jdbc 试试
tuo_bing 2010-01-21
  • 打赏
  • 举报
回复
mark,关注 。。。
小霍夫 2010-01-21
  • 打赏
  • 举报
回复
你项目真大。百w级数据。
xuexijava 2010-01-21
  • 打赏
  • 举报
回复
学习
privateWitkey 2010-01-21
  • 打赏
  • 举报
回复
也在研究这问题.关注此贴
H_ChaoShi 2010-01-21
  • 打赏
  • 举报
回复
数据优化一直是难题, 学习....
crazy915 2010-01-21
  • 打赏
  • 举报
回复
没有正式用过Hibernate..

但看过Hibernate的源码,,Hibernate 2针对于sqlserver 的分页只是逻辑分页。。

好像Hibernate 3也是逻辑分页。。。

只会在sql数据的时候在上top,只有第一页数据会出现的比较快,,而后翻页是查询出来的数据越来越多,再通过翻动游标返回数据。。。

像我正在用的ibatis也是如此,,,这些orm都唯独不支持sqlserver的物理分页。。

解决办法,,,楼主网上应该一大吧。。。基本上应该重载sqlserver的方言。。。

其实200w的数据也不算多,,,

贴点源码:
orcle:
public String getLimitString(String sql, boolean hasOffset) {
sql = sql.trim();
boolean isForUpdate = false;
if ( sql.toLowerCase().endsWith(" for update") ) {
sql = sql.substring( 0, sql.length()-11 );
isForUpdate = true;
}

StringBuffer pagingSelect = new StringBuffer( sql.length()+100 );
if (hasOffset) {
pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
}
else {
pagingSelect.append("select * from ( ");
}
pagingSelect.append(sql);
if (hasOffset) {
pagingSelect.append(" ) row_ where rownum <= ?) where rownum_ > ?");
}
else {
pagingSelect.append(" ) where rownum <= ?");
}

if ( isForUpdate ) {
pagingSelect.append( " for update" );
}

return pagingSelect.toString();
}

sqlserver:

public String getLimitString(String querySelect, int offset, int limit) {
if ( offset > 0 ) {
throw new UnsupportedOperationException( "sql server has no offset" );
}
return new StringBuffer( querySelect.length()+8 )
.append(querySelect)
.insert( getAfterSelectInsertPoint(querySelect), " top " + limit )
.toString();
}
sw4433 2010-01-20
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 tianwailaifenglove 的回复:]
使用hibernate建议配上二级缓存,不然数据量大了,是非常耗性能的,而且你的延迟加载等等都得设置好,和主控,级联,不然极有可能把你的整个数据库给load出来
hibernate做的最好的就是缓存
[/Quote]

二级缓存 什么个意思?
怎么设置?
不吃鱼的熊 2010-01-20
  • 打赏
  • 举报
回复
[Quote=引用楼主 sw4433 的回复:]
hibernate已实现分页查询,查询前面的数据速度很快,但查询后面的数据就很慢:

比如我现在是200,0000条记录,
页面 是:首页 上一页 下一页 尾页

点首页或点下一页查询很快,但点尾页就要十几秒才能查询到,此时再点上一页也是需要十几秒才能查询到

也就是说越往后的数据查询的越慢,有什么好的办法能解决此问题?

有没有比较好的方法能显著提升速度?
[/Quote]
可以从多方面下手:第一,可以为查询的设置索引;第二,优化查询,使用数据库分页(如Oracle的伪列);第三,用数据库存储过程来分页,返回一页的数据,也挺好。
crazylaa 2010-01-20
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 tianwailaifenglove 的回复:]
使用hibernate建议配上二级缓存,不然数据量大了,是非常耗性能的,而且你的延迟加载等等都得设置好,和主控,级联,不然极有可能把你的整个数据库给load出来
hibernate做的最好的就是缓存
[/Quote]
哦?二级缓存什么意思?是不是比如我每页要查10条,但是它给我查一百条出来,然后每次翻页就从缓存里面拿啊?如果不是这样的话,难道200w也一次都放内存?
我不懂hib啊,纯粹瞎猜的,不用当真。
眼神eye 2010-01-20
  • 打赏
  • 举报
回复
使用hibernate建议配上二级缓存,不然数据量大了,是非常耗性能的,而且你的延迟加载等等都得设置好,和主控,级联,不然极有可能把你的整个数据库给load出来
hibernate做的最好的就是缓存
crazylaa 2010-01-20
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 sw4433 的回复:]
id为主键,等于有索引了

速度还是很慢,Hinernate 难道只能就这样了?
[/Quote]
没办法,我的机器1G内存,双核,也是只有PK的索引,oracle92数据库,200w数据,有order by,取最后10条也差不多这个时间(sql跟你的一样。。。)
加载更多回复(11)

81,094

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧