最近工作做了一个优化:一个数据表有几百万甚至千万条的记录,符合条件的也有十几万条,要取出来出到excel里做报表,原来是一次性读取到一个sheet,直到一个sheet放不下系统出错,才开始修正这个问题。
    我首先想到的是分页(分sheet)显示数据,于是读取的话也分页读取,而不是一次性读取出来,然后拆分结果集。实现之后一个最佳效率的问题自然而然的就产生了,oracle分页,每页大小多少最佳?(现在是65536,也就是excel2003的最大值)。也就是如果只考虑查询速度,在最短的时间内查出所有的值,每页到底该有多大?首先我感觉一次性读取全部内容效率应该不是最高的(直观感觉),另一种极端情况,一页一条记录,读取十几万次应该也不是最好的,所有中间比应该有个最优值,这个值该怎么算?谁研究过?

解决方案 »

  1.   

    如果你的数据全都要,分不分页意义不太大。
    或者分到每页65536,好像EXCEL表行数最大是65536。
      

  2.   

    要取出来出到excel里做报表ok   好吧,我落伍了,原来现在的  "报表"  可以是这么大,估计N多EXCEL才可以装的下吧?如果这样子的话,我想你们系统的用户体验度会差到一定程度吧?如果我是用户,看着这一堆系统产生的报表不发愁才怪.
      

  3.   

    都没弄个明白什么意思!用户知道一页多大最快吗?我目前自己的实现是65536是为了省事,一次的结果集正好装满一个sheet页,正式因为我觉得这个问题还有得研究,才让大家想想到底设置多大可以最快!
      

  4.   

    这个速度与取多大没有太大关系,与你的sql语句、硬件什么的关系比较大,不信你可以取6w和2w试试,生成所有报表用的时间差不多。
      

  5.   


    SELECT * FROM   
    (  
    SELECT A.*, ROWNUM RN   
    FROM (SELECT * FROM TABLE_NAME) A   
    WHERE ROWNUM <= 40  
    )  
    WHERE RN >= 21  
    我的sql是类似这样的。    SELECT * FROM TABLE_NAME 是最终的查询语句 。。
      

  6.   


    没用啥框架,就是JDBC直接跑sql
      

  7.   

    那试试用JDBC写个查询获得ResultSet之后,一行一行的读每读出一行来,就写到Excel中去。这样号称占内存少
      

  8.   

    这类问题似乎应该去Oracle板块问。私以为所有优化性能的出发点都应该是从瓶颈入手,这里的性能瓶颈,初步估计应该是网络IO。那么,既然你反正都是每次要搞定全部的几十万条记录,其实也没必要考虑什么分页了,直接全表Select,然后服务器端游标直接全部搞定,以网络吞吐量为优先考虑好了。反正到了65535就重开新的Excel,流式操作也不会对内存造成太大压力。考虑引入分页的合理性是:如果你打算用多线程来干这事。但前面估计了,与硬盘IO或CPU负载比起来,网络IO应该才是瓶颈,而分页并不能对网络IO起到优化作用,所以多线程的合理性就很低了。最后一个小建议,既然要拆分记录,也许取个整数更便于使用,比如第一个Excel就是1~5W,第二个5W1~10W。
      

  9.   

    呵呵,没注意是做报表用的
    shell+ sqlload
    建表索引和分区都加上,导入很快
    导出的话,csv不行么?
      

  10.   


    我们纯java,怎么调shell没搞过,不过csv确实不行,客户有些确实会看。csv的没格式。。