论坛首页 Java企业应用论坛

Web下的分页显示性能,怀疑99%的人都没完全搞清楚,希望们能给个终极答案

浏览 5387 次
该帖已经被评为隐藏帖
作者 正文
   发表时间:2007-04-28  
1、执行select * from tab1 而不移动游标,DBServer会把数据全载入内存吗?如果“否”,游标从头移到尾,数据全载入内存吗?
2、jdbc返回ResultSet时,数据就全部从DBServer到AppServer了吗?不同类型的ResultSet,这点上有差别吗?
3、AppServer上的游标next(),需要和DBServer通讯吗?
4、不同的数据库厂家,不同的jdbc驱动,上述问题都一样吗?



希望[[[]]]们能给个终极答案


javaeye为什么要屏蔽[daxia]两个字?还是标题太长?
   发表时间:2007-04-28  
可以参考一下Hibernate的分页实现:
以下是Spring的HibernateTemplate类对于Hibernate的分页功能的封装代码:
public List findByCriteria(final DetachedCriteria criteria, final int firstResult, final int maxResults)
	throws DataAccessException {

	Assert.notNull(criteria, "DetachedCriteria must not be null");
	return (List) execute(new HibernateCallback() {
		public Object doInHibernate(Session session) throws HibernateException {
			Criteria executableCriteria = criteria.getExecutableCriteria(session);
			prepareCriteria(executableCriteria);
			if (firstResult >= 0) {
				executableCriteria.setFirstResult(firstResult);
			}
			if (maxResults > 0) {
				executableCriteria.setMaxResults(maxResults);
			}
			return executableCriteria.list();
		}
	}, true);
}

你需要了解一下Hibernate的Criteria类在执行了setFirstResult和setMaxResults两个方法之后做了些什么事情。我也没有仔细读过Hibernate这方面的实现。不过Hibernate对于数据分页,提供了较为理想的解决方案,使得开发者不必自己去关注具体数据库JDBC driver的实现细节。基于Hibernate的应用,一般数据分页最终都是调用Hibernate本身提供的分页支持。
0 请登录后投票
   发表时间:2007-04-28  
1、执行select * from tab1 而不移动游标,DBServer会把数据全载入内存吗?如果“否”,游标从头移到尾,数据全载入内存吗?

>> 不知道。不过我相信数据库在这方面做的优化已经非常成熟了。

2、jdbc返回ResultSet时,数据就全部从DBServer到AppServer了吗?不同类型的ResultSet,这点上有差别吗?

>> 当然没有,顶多是预取一部分数据,取多少可以自己指定。

3、AppServer上的游标next(),需要和DBServer通讯吗?

>> 如果不需要的话,就不会抛出异常了。

4、不同的数据库厂家,不同的jdbc驱动,上述问题都一样吗?

>> 反正都是按照标准,以最优化的方式实现。
0 请登录后投票
   发表时间:2007-04-28  
to yiding_he,dlee:

我感觉DB端的cache策略、jdbc客户端的cache策略,各个厂家和驱动之间应该是有差别的。

比如我跟踪查过hsqldb jdbc的next(),就没访问socket的代码。但象oracle等大型库,应该是有的,谁能确认一下?
0 请登录后投票
   发表时间:2007-04-28  
1、执行select * from tab1 而不移动游标,DBServer会把数据全载入内存吗?如果“否”,游标从头移到尾,数据全载入内存吗?
>>>要根据分类和要求处理的,并不能简单的回答是与否。
2、jdbc返回ResultSet时,数据就全部从DBServer到AppServer了吗?不同类型的ResultSet,这点上有差别吗?
>>>不一定,加入数据少的话,自然就全部,否则的话只是一部分,至于这个数据量是可以自己设定的。
3、AppServer上的游标next(),需要和DBServer通讯吗?
>>>当全部到APPServer的时候自然就不需要与DbServer通讯了,和2是密切相关的。
4、不同的数据库厂家,不同的jdbc驱动,上述问题都一样吗?
>>>都差不多,只是细节实现处理的区别,至少我测试过的几个数据库是如此。
0 请登录后投票
   发表时间:2007-04-28  
继续明确问题:

1、在DBServer中,一条完整的记录数据是什么时间载入内存的?连续N个空的next(),与relative(N)有多大差别?

2、上面两位已经算已经解决。


3.4、jdbc端,对小型数据库:经查jdbc驱动代码,hsqldb 的ResultSet总是取回所有数据,next()不会发生网络通讯;mysql driver(5.0.5)的statement产生的结果集也总是取回所有数据,preparedstatement产生的结果集,比较搞笑:We only stream result sets when they are forward-only, read-only, and the fetch size has been set to Integer.MIN_VALUE。也就是说,默认情况下也是取所有数据;如果硬设为动态结果集,则不支持relative()、isLast()等,因此其动态结果集实现不成熟。大库看了oracle的,scrollable结果集也是一次全部装入,普通结果集在next()逸出时要访问服务器。

初步结论是:如果用游标移动来翻页,小库适合用relative(N),但差别极小;而oracle用next()总体效率更高

原先设想:jdbc端,如果缓存用完,继续next(),但不进行.getXXX(),jdbc驱动有没可能优化成:.getXXX()发生时才取数据。看了这几个驱动,感觉是没厂家会这么做了,看来在DB端先减少结果集行数确实是必要的。
0 请登录后投票
   发表时间:2007-04-29  
1.全部载入
2。返回ResultSet时,数据全部到内存
3.rs.next()不与db交互
4.一样
0 请登录后投票
   发表时间:2007-04-29  
从实际应用的角度来说
一个返回成千上万条记录的查询是无意义的
在statement对象上可设置maxrows参数
设个2000条足够了
0 请登录后投票
   发表时间:2007-04-29  
http://www.iteye.com/topic/21886?page=2

我感觉是hibernate 在操作sqlserver和mysql时有些许不同,感觉mysql自己应该有缓存数据,不知道对分页会不会有影响
0 请登录后投票
   发表时间:2007-04-29  
呵呵.所以对于多的数据,肯定要设置maxRows的.
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics