是这样的,例如我有一个B.JSP页面这个页面上有15个下拉框(姑且不讨论这样做是否合理).每个下拉框都对应不同的表去查找数据,那么当我从A.JSP页面转向到ACTION之后 在ACTION的方法体当中通过后台的方法去对每张表进行查询,查询每张表都会调用不同的方法,然后在ACTION里面把每个集合丢到request中返回到B.jsp页面 可是这样一来相当于打开了十几个数据库连接,这样页面在打开的时候相当的慢,我能想到得办法就是写一个方法 只打开一个数据库连接 然后在这个方法中写十几个查询数据库的语句对应不同的表,然后查出来的所有集合都丢到一个集合当中,返回到ACTION在循环取出每个集合。可是这样并非是个好办法。视图也想过,但是每个下拉框的数据都要指定一个标识才能查询到对应的集合,这样一来也不太好。现在想问问大家 各位遇到这种情况一般是怎么处理的?

解决方案 »

  1.   

    使用连接池,可以试一下在一个sql里查出所有15个表的数据,或者使用存储过程
    尝试优化sql
    不知道你的具体问题是什么
      

  2.   

    用Ajax方式、用户点击了才跑到数据库去查询~~~!!!
      

  3.   


    你好,可能是我叙述的太罗嗦了。其实就是 我要去一次性查询15张表中的数据,每张表查询的方法都打开了一个数据库的连接,只用JAVA代码实现。看是否有什么好一些的优化措施。让速度变得更快一些。
      

  4.   


    我知道,可以把这些都放在一个方法里面,那么只需要打开一次连接就可以 可是这样的方法 查询还是必不可少的也不是什么好办法。并且即使将这些集合拿到了 在ACTION还要在把每个集合循环出来,效率不见得能高多少。
      

  5.   

    可从以下两个方面着手
    1、减少数据库连接
    2、减少网络传输
    具体情况具体分析,这15个下拉框的数据能否做个分类,放在一张表里面,比如分为id, 类别,名称,备注,一个类别对应一个下拉框。从A页面经过Action的时候,一次性把这些数据取到,形成一个JSON字符串,到B页面的时候通过脚本做解析,跟每个下拉框对应起来。(也不用形成JSON字符串,也可以在后台做分解再通过B页面获取,不过这样效果就差一点了)
    如果这些数据不能放在同一个表,可通过视图,构造要返回的字段,达到同一张表的目的。
    这样做,连接一次数据库,一次请求,一次响应。
      

  6.   


    对于我昨天的回帖。抱歉了。。
    晚上看了下oracle的性能优化大全发现LZ这种情况可以做优化。。如下案例:第三种方式正好适合LZ。。
    7.     减少访问数据库的次数
    当执行每条SQL语句时, ORACLE在内部执行了许多工作: 解析SQL语句, 估算索引的利用率, 绑定变量 , 读数据块等等. 由此可见, 减少访问数据库的次数 , 就能实际上减少ORACLE的工作量.
     例如,
        以下有三种方法可以检索出雇员号等于0342或0291的职员.
     方法1 (最低效)
        SELECT EMP_NAME , SALARY , GRADE
        FROM EMP 
        WHERE EMP_NO = 342;
         SELECT EMP_NAME , SALARY , GRADE
        FROM EMP 
        WHERE EMP_NO = 291;
    方法2 (次低效)
           DECLARE 
            CURSOR C1 (E_NO NUMBER) IS 
            SELECT EMP_NAME,SALARY,GRADE
            FROM EMP 
            WHERE EMP_NO = E_NO;
        BEGIN 
            OPEN C1(342);
            FETCH C1 INTO …,..,.. ;
                    OPEN C1(291);
           FETCH C1 INTO …,..,.. ;
             CLOSE C1;
          END;
    方法3 (高效)
        SELECT A.EMP_NAME , A.SALARY , A.GRADE,
                B.EMP_NAME , B.SALARY , B.GRADE
        FROM EMP A,EMP B
        WHERE A.EMP_NO = 342
        AND   B.EMP_NO = 291;
     注意:
    在SQL*Plus , SQL*Forms和Pro*C中重新设置ARRAYSIZE参数, 可以增加每次数据库访问的检索数据量 ,建议值为200.
      

  7.   

    可以将多个表的多个你需要的字段拼成一条SQL查询,在代码里面解析这个SQL返回的记录,按界面需要拆分
      

  8.   

    楼主的问题是否可以归结成一次查询15张表,怎么提高速度
    其实还是放在一个sql里去完成所有的查询,我想着是用union all去连接结果集,这样只需要1次连接,1ge 游标,1次解析,1次执行。
    如果实时不高而且每次查询谓词都相同的话可以考虑使用物化视图
    11g的话如果表更新不频繁的话对每个表的查询提示使用结果缓存select /*+ result_cache*/ ...
    如果查询性能还是有问题,就可以看下自己的sql有没有问题,自己可以简单的优化一下,如强选择性字段上建索引
    还有问题就交给你的DBA处理吧
      

  9.   


    方法3 (高效)
            SELECT A.EMP_NAME , A.SALARY , A.GRADE,
                    B.EMP_NAME , B.SALARY , B.GRADE
            FROM EMP A,EMP B
            WHERE A.EMP_NO = 342
            AND   B.EMP_NO = 291;这种方式,你难道说不是一次连接?能不用union all为什么硬要去用。。用union all又有额外的性能牺牲。。
      

  10.   

     服务器启动的时候,将所有的15张表数据放到application里面,每次用的时候直接去application里面去读取,为每个表都单独设置一个存储在application里面的方法,还有一个存储总的方法,每次对应的表有修改操作的时候就调用一下那个单个方法。这样实现起来比较简单,也很直观
      

  11.   

    我自己没见过这种写法
    你这个其实是一个交叉连接,或者说是一个笛卡尔积连接
    举个例子你看下SELECT A.ENAME , A.SAL ,
      B.ENAME , B.SAL 
      FROM EMP A,EMP B
      WHERE A.EMPNO = 7499
      AND B.EMPNO = 7369;执行计划是
    -------------------------------------------------------------------------------------------------
    | Id  | Operation                    | Name   | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    -------------------------------------------------------------------------------------------------
    |   1 |  NESTED LOOPS                |        |      1 |      1 |      1 |00:00:00.01 |       4 |
    |   2 |   TABLE ACCESS BY INDEX ROWID| EMP    |      1 |      1 |      1 |00:00:00.01 |       2 |
    |*  3 |    INDEX UNIQUE SCAN         | EMP_PK |      1 |      1 |      1 |00:00:00.01 |       1 |
    |   4 |   TABLE ACCESS BY INDEX ROWID| EMP    |      1 |      1 |      1 |00:00:00.01 |       2 |
    |*  5 |    INDEX UNIQUE SCAN         | EMP_PK |      1 |      1 |      1 |00:00:00.01 |       1 |
    -------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):
    ---------------------------------------------------   3 - access("B"."EMPNO"=7499)
       5 - access("A"."EMPNO"=7369)你可以看到操作2和4进行了一个相关联合型操作(NESTED LOOPS 嵌套循环操作),虽然两者都只返回一条记录SELECT A.ENAME , A.SAL ,
      B.ENAME , B.SAL 
      FROM EMP A,EMP B
      WHERE A.EMPNO > 7900
      AND B.EMPNO > 7902;执行计划
    --------------------------------------------------------------------------------------------------
    | Id  | Operation                     | Name   | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    --------------------------------------------------------------------------------------------------
    |   1 |  MERGE JOIN CARTESIAN         |        |      1 |      1 |      2 |00:00:00.01 |       6 |
    |   2 |   TABLE ACCESS BY INDEX ROWID | EMP    |      1 |      1 |      2 |00:00:00.01 |       4 |
    |*  3 |    INDEX RANGE SCAN           | EMP_PK |      1 |      1 |      2 |00:00:00.01 |       2 |
    |   4 |   BUFFER SORT                 |        |      2 |      1 |      2 |00:00:00.01 |       2 |
    |   5 |    TABLE ACCESS BY INDEX ROWID| EMP    |      1 |      1 |      1 |00:00:00.01 |       2 |
    |*  6 |     INDEX RANGE SCAN          | EMP_PK |      1 |      1 |      1 |00:00:00.01 |       1 |
    --------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):
    ---------------------------------------------------   3 - access("A"."EMPNO">7900)
       6 - access("B"."EMPNO">7902)
    这个就比较典型了,2和5执行了一个非相关联合操作的笛卡尔积合并连接,但是出现了一次排序而union all是一个典型的非相关联合操作SELECT ENAME , SAL 
      FROM EMP WHERE EMPNO > 7900
      UNION ALL
      SELECT ENAME , SAL 
      FROM EMP WHERE EMPNO > 7902执行计划-------------------------------------------------------------------------------------------------
    | Id  | Operation                    | Name   | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    -------------------------------------------------------------------------------------------------
    |   1 |  UNION-ALL                   |        |      1 |        |      3 |00:00:00.01 |       6 |
    |   2 |   TABLE ACCESS BY INDEX ROWID| EMP    |      1 |      1 |      2 |00:00:00.01 |       4 |
    |*  3 |    INDEX RANGE SCAN          | EMP_PK |      1 |      1 |      2 |00:00:00.01 |       2 |
    |   4 |   TABLE ACCESS BY INDEX ROWID| EMP    |      1 |      1 |      1 |00:00:00.01 |       2 |
    |*  5 |    INDEX RANGE SCAN          | EMP_PK |      1 |      1 |      1 |00:00:00.01 |       1 |
    -------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):
    ---------------------------------------------------   3 - access("EMPNO">7900)
       5 - access("EMPNO">7902)
      

  12.   

    从新理一下思路吧 SQL上面的操作是不可避免的
      

  13.   

    使用ehcache可以很好解决这个问题。。
      

  14.   

    感谢各位的回复与帮助,最后还是采纳了13楼的回复,用户在请求主页面的时候就把所有的数据查询出来放在JSON里面 以后查的话直接去调保存在该页面中的数据。与数据库再无关联了,没有去做数据库优化是因为 15个查询各自有各自的查询条件。感谢各位的帮助。
      

  15.   

    refactory database struct itself.
      

  16.   

    如果你坚持使用SQL
    无论如何,最佳的方法是只打开一次数据库连接,这个并不难做到,除非你数据库操作DAO和数据库操作那些基础类设计的实在太烂。和你具体查询什么,传入查询条件都无关!你这个根本不是什么问题
      

  17.   

    如果某种框架,不会不带连接池的吧。除非大并发访问,所以耗在获取连接上的时间应该不多的。没什么好优化的。
    要查15个表,又是异步,所以执行15个查询也是必须的。数据库执行这点规模的计算实在不算什么,除非都是查的海量数据,条件和索引又都没优化。
    剩下的就是包装数据和传输到客户。客户端解析数据。
    你可以试试单独执行sql的时间,和前台点击后得到数据的时间。相差无几就从sql语句下手。
    如果sql执行的飞快,但是前台展现数据的时间长,就要优化数据封装和解析的方式。