论坛首页 入门技术论坛

小论分页方案

浏览 8314 次
该帖已经被评为新手帖
作者 正文
   发表时间:2007-06-17  
时不时看到有人在讨论分页问题,今天有空也做了一个方案,展示给大家:
public class PageResultTest extends TestBase {
    private volatile int leavingThreadNum;

    public void testGet() throws Exception {
        importHugeAccountData(100000);

        long startTime = System.currentTimeMillis();
        final PageResult pageResult = new PageResult(Account._, null, null, 100);
        final Random rand = new Random();
        int threadNum = 100;
        leavingThreadNum = threadNum;

        for (int i = 0; i < 100; i++) {
            Thread t = new Thread() {
                    public void run() {
                        pageResult.refresh();

                        int pageNumber = rand.nextInt() % pageResult.pageCount();
                        pageNumber = Math.abs(pageNumber);
                        pageNumber = (pageNumber == 0) ? 1 : pageNumber;

                        // println(pageNumber);
                        ResultList page1 = pageResult.getPage(pageNumber);
                        // println(page1.getLie(Account.ID));
                        assertEquals(100, page1.size());

                        long firstId = page1.get(Account.ID);
                        assertEquals(1, firstId - (100 * (pageNumber - 1)));
                        leavingThreadNum--;
                    }
                };

            t.start();
        }

        while (leavingThreadNum > 0) {
            Thread.sleep(10);
        }

        System.out.println(threadNum + " thread take time: " +
            (System.currentTimeMillis() - startTime));
    }

测试结果:
100 thread take time: 2469

从任务管理器里观察到javaw.exe的内存:
开始是内存为:
20,232KB
结束是内存为:
71,620KB

上面程序的意思是:
1,先导入100,000条account记录到数据库
2,用下面语句建立分页,每页100条记录,共1000页:
final PageResult pageResult = new PageResult(Account._, null, null, 100);

3,然后同时运行100个线程,每个线程从1000页中随机取一页。
4,打印花费的时间:
100 thread take time: 2469


说明:
1,cache这些页面大概花去50MB内存。
2,之所以花去50MB内存,主要是因为取页面是随机。
在实际应用中我们通常取的页面很可能不超过10,可能前面4~5页和最后面的1~2页,因此cache这项页面化的内存不会超过10MB。
3,这些cache页面花去的内存会被自动收回,如果一个页面在5分钟内没用到,就会从cache中remove掉。
4,可以看到这种分页方案非常简单,整个分页重要一条语句。速度极快,100线程只花了2.5秒。
5,测试环境:
jdk: 6.0, OS: winxp, servicpack2, cpu:p4 2.8G, memory: 1.5G, database: mysql 5.0, IDE: eclipse 3.2
   发表时间:2007-06-17  
你在哪里分页了?
0 请登录后投票
   发表时间:2007-06-17  
我想我是海 写道
你在哪里分页了?

在:
final PageResult pageResult = new PageResult(Account._, null, null, 100);

下面是PageResult接口:
public interface PageResult<T> {
    ResultList firstPage() throws CoatException;
    ResultList lastPage() throws CoatException; 
    ResultList previousPage() throws CoatException;
    ResultList nextPage();
    ResultList getPage(int pageNumber) throws CoatException;
    ResultList goToPage(int pageNumber) throws CoatException;
    ResultList exchangePage(int pageNumber1, int pageNumber2)  throws CoatException;
    int pageCount(); 
    int lineCount(); 
    int pageSize();
    int getCurrentPageNumber();
    void absolute(int pageNumber);
    void refresh() throws CoatException;
    void clear();
}
0 请登录后投票
   发表时间:2007-06-17  
等着看完整的代码
0 请登录后投票
   发表时间:2007-06-17  
分页,好像是程序开发中每个人都感兴趣的话题,性能,大数据量访问,当然,这也是软件开发中最复杂的一面,大并发量,最近做一个项目,其中用到EJB,spring ,jms ,jni, 发现,很复杂,业务逻辑很复杂。
0 请登录后投票
   发表时间:2007-06-18  
数据量太少

我们这有个表  自身的count(*) 最少都要运行5分钟
0 请登录后投票
   发表时间:2007-06-18  
我想我是海 写道
等着看完整的代码

目前没有原始代码给你,不过可以写一个简单的示例:
public class PageResult {

private ResultSet rs;
private Map<String, ResultList> cache = new HashMap<String, ResultList>();
private int currentPageNumber;

public ResultLList firstPage() {
    return goToPage(1);
}

public ResultList goToPage(int pageNumber) {
    ResultList page = getPage(pageNumber);
    currentPageNumber = pageNumber;
    return page;
}

public ResultList getPage(int pageNumber) {
     ResultList page = cache.get(pageNumber);
     if (page == null) {
          ......
          // get result from ResultSet;
          .....
     
     }
     return page;
}
..........
}

我自己的实现跟上面有点不同。
我用到自己以前写的框架:
http://sourceforge.net/projects/dbcoat
0 请登录后投票
   发表时间:2007-06-18  
ddandyy 写道
数据量太少

我们这有个表  自身的count(*) 最少都要运行5分钟



你们多少数据?
我刚才导入1000,000数据测了一下,200个线程,测试结果:
200 thread take time: 16704

还不错吧
0 请登录后投票
   发表时间:2007-06-19  
这是方案 ?
想把算法卖给大家 ?
0 请登录后投票
   发表时间:2007-06-19  
我倒是测过oracle的sql拿指定行

在1W行以前是有很大差别的  越靠前速度越快
过1W行之后 速度几乎都是一样的了
0 请登录后投票
论坛首页 入门技术版

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