当前位置: 技术问答>java相关
高分求分页算法(优化)
来源: 互联网 发布时间:2015-03-30
本文导语: 欲分页的文件的入口变量是String sql和int p,默认每页20条记录,由此可以得到一个rs。必须这样。 一般的分页算法鄙人已经很熟悉了。但是在数据量相当庞大的时候,就涉及到一个效率的问题。 我已经尝试过的两...
欲分页的文件的入口变量是String sql和int p,默认每页20条记录,由此可以得到一个rs。必须这样。
一般的分页算法鄙人已经很熟悉了。但是在数据量相当庞大的时候,就涉及到一个效率的问题。
我已经尝试过的两种办法是:
1.先通过rs得到一个保存主键的String[],这个数组可以用一般的分页算法保持大小。然后把rs释放掉,再在for数组长度的循环中,使用主键进行一个相对教小的查询,这样可以避免页面中长时间的存在一个大记录集。但是和可惜测试效果很不理想,估计是因为涉及到太多的数据库查询。
2.就使用大记录集,但是在确定不同页的起始位置时遇到了问题,由于DB2的JDBC中不支持java.sql.ResultSet.absolute(),所以只能用for循环进行很多次rs.next(),这种办法在前几页还可以,但是明眼人很容易就可以看出,效率与页数是完全成反比的。如果直接到最后页,简直慢得吓人,因为对一个大记录集next了n次。
请问有这方面经验的朋友,我怎样才可以尽量高效的通过一个sql和一个p得到一仅仅有20行记录的小数据集?
一般的分页算法鄙人已经很熟悉了。但是在数据量相当庞大的时候,就涉及到一个效率的问题。
我已经尝试过的两种办法是:
1.先通过rs得到一个保存主键的String[],这个数组可以用一般的分页算法保持大小。然后把rs释放掉,再在for数组长度的循环中,使用主键进行一个相对教小的查询,这样可以避免页面中长时间的存在一个大记录集。但是和可惜测试效果很不理想,估计是因为涉及到太多的数据库查询。
2.就使用大记录集,但是在确定不同页的起始位置时遇到了问题,由于DB2的JDBC中不支持java.sql.ResultSet.absolute(),所以只能用for循环进行很多次rs.next(),这种办法在前几页还可以,但是明眼人很容易就可以看出,效率与页数是完全成反比的。如果直接到最后页,简直慢得吓人,因为对一个大记录集next了n次。
请问有这方面经验的朋友,我怎样才可以尽量高效的通过一个sql和一个p得到一仅仅有20行记录的小数据集?
|
to tiangou(分数不多就去灌水乐园)
假设这种情况:
我有一个产品目录,其中有10000个产品,每个产品纪录占用1KB的空间,如果按你的方法,把它们全部查询出来,占用内存空间10MB左右,如果100个用户同时进行这个操作,要占用1GB左右的内存:)
ps:10000个产品算少的了,我们做过一个项目,产品目录中共有300多万条纪录,如果select *,JVM就直接死翘翘了:)
分页不是那么简单的,必须实现缓冲的机制。
假设这种情况:
我有一个产品目录,其中有10000个产品,每个产品纪录占用1KB的空间,如果按你的方法,把它们全部查询出来,占用内存空间10MB左右,如果100个用户同时进行这个操作,要占用1GB左右的内存:)
ps:10000个产品算少的了,我们做过一个项目,产品目录中共有300多万条纪录,如果select *,JVM就直接死翘翘了:)
分页不是那么简单的,必须实现缓冲的机制。
|
这类问题的解决应从两方面着手.
第一、优化数据库,建立高效索引,比如可以对ID(连续的整型主键)建立索引。这样一来在牺牲了一定的记录更新速度。但却数倍提高查询速度。
第二、采用高效的查询算法和精炼的查询语句。用SESSION等本地缓冲方法显然是得不偿失的,这样会过大增加服务器内存开销。
1既然是翻页,那么可以肯定的一点是,没条记录的大小是有限的,万一需要显示大字段,如图片等,那么不妨分次查询,第一次只查出基本的数据显示出来,完毕后再查大字段。
第一、优化数据库,建立高效索引,比如可以对ID(连续的整型主键)建立索引。这样一来在牺牲了一定的记录更新速度。但却数倍提高查询速度。
第二、采用高效的查询算法和精炼的查询语句。用SESSION等本地缓冲方法显然是得不偿失的,这样会过大增加服务器内存开销。
1既然是翻页,那么可以肯定的一点是,没条记录的大小是有限的,万一需要显示大字段,如图片等,那么不妨分次查询,第一次只查出基本的数据显示出来,完毕后再查大字段。
|
可以考虑使用临时文件的方式
|
追求不一般的效率恐怕和数据库相关了
比如mysql 可以用limit
SQLServer支持PageSize
Oracle 有时可以使用minus,决大多数是用JDBC2的特性,绝对指针定位
我对DB2不是很熟悉,不过absolute()是JDBC2.0的特性,是和数据库相关吗?你用的是JDBC2.0吗?
比如mysql 可以用limit
SQLServer支持PageSize
Oracle 有时可以使用minus,决大多数是用JDBC2的特性,绝对指针定位
我对DB2不是很熟悉,不过absolute()是JDBC2.0的特性,是和数据库相关吗?你用的是JDBC2.0吗?
|
与驱动程序有关?
桥接器支持游标定位。
桥接器支持游标定位。
|
我是这样处理的,
1、定义一个Vector矢量,将rs中的数据全部保存到Vector中,释放rs,即rs.close();
2、由上一步的rs.next()同时可以得到总记录数,由此得到总共的页数,每条记录的列数
3、将Vector矢量保存至session中
4、从session中取出Vector矢量,根据页数和每条记录的列数再从Vector中取出所要数据
1、定义一个Vector矢量,将rs中的数据全部保存到Vector中,释放rs,即rs.close();
2、由上一步的rs.next()同时可以得到总记录数,由此得到总共的页数,每条记录的列数
3、将Vector矢量保存至session中
4、从session中取出Vector矢量,根据页数和每条记录的列数再从Vector中取出所要数据
|
首先确定分页机制要使用缓存,每次只从DB取出固定数量的数据。
如果数据库是Oracle可以通过ROWNUM来实现,如果是SQL Server可以通过TOP N来实现,DB2不太清楚。
如果数据库是Oracle可以通过ROWNUM来实现,如果是SQL Server可以通过TOP N来实现,DB2不太清楚。
|
还可以用存储过程和游标来解决吧,直接返回个对象,就是查询的结果集
可惜不懂DB2数据库
可惜不懂DB2数据库
|
to 回复人: hccpro(hcc)
我认为是每页都查,
放session 里将给服务器造成极大的负担,
得不偿失
我认为是每页都查,
放session 里将给服务器造成极大的负担,
得不偿失
|
oracle可以select * from tab where rownum