这样的,我的存储过程外面是一个loop来循环一张表,里面有12个查询,和一些插入操作。现在单是每条查询,就有30到60毫秒。那么是不是说,这个存储过程loop每次循环都要几百毫秒。
   如果是这样,现在我要处理800万数据的表,就是说loop循环800万次,这个速度太慢了,怎么解决?
   新手小白,望高手指点啊!

解决方案 »

  1.   

    -- 不能简单这么理解,
    -- 尤其是存储过程中存在循环或变量赋值的时候,必须有个“上下文切换”操作过程,也需要耗费一定的时间!
    -- 所谓“上下文切换”是指在存储过程中Oracle从SQL环境切换到PL/SQL环境!
      

  2.   

    loop循环一张表,你可以把这张表只存进去1000条,看看时间是多少,然后再估算下时间,看看耗时,感觉像你上面那么估算肯定不准确。
    另外可以用job实现存储过程的并行执行
      

  3.   

    不要把sql当作一步一步的数据处理过程。换个思路:把sql处理的数据当作一个集合,再来写sql,可能效率会高点。
      

  4.   

    简化一下就是这样,loop里有6个相似的过程,我就写了一个了
    CURSOR c1 
    LOOP
          OPEN xzzdz_cursor FOR
          SELECT dzbh,xxdz FROM ent_wszz.ENTITY_DZ t1 WHERE t1.xxdz = v_xzz;
          FETCH xzzdz_cursor INTO xzzdz_record;      IF(..) THEN 
            SELECT COUNT(1) INTO d_flag FROM ENT_WSZZ.ENTITY_link 
            WHERE stabh='..' AND stbbh='...';         
          IF(d_flag= 0) THEN
            INSERT INTO......END LOOP
      

  5.   

    c1 800多万
    ENTITY_DZ 暂时1000万数据
    ENTITY_link  暂时4000万数据
      

  6.   

    首先,你根据每条查询的30、50毫秒来推测执行12次的时间是不准的,因为单条查询的时间包括硬解析、软解析时间,所以单次时间参考性不大。
    其次,你可以在循环中批量commit,例如1万条commit一次,提升性能。
    再次,优化你的查询、更新SQL,增加索引、使用merge等方法来提升更新性能。下面给你个例子吧:
    MERGE INTO TAB1 A
    USING TAB2 B
    ON (A.POLICY_NO = B.POLICY_NO)
    WHEN MATCHED THEN
      UPDATE
         SET A.PLAN_CODE    = B.PLAN_CODE,
             A.UPDATED_DATE = SYSDATE,
             A.UPDATED_BY   = 'SYSTEM'
    WHEN NOT MATCHED THEN
      INSERT VALUES (B.POLICY_NO, 'SYSTEM');
      

  7.   

    相对于loop 800万次的开销,单纯只优化查询时不行的,楼主应该考虑优化算法。
      

  8.   

    9#说的对,有时一条语句下去可能无任何结果,有时可能影响到非常多的记录。
    如5楼的,可以存一些数据测试看看。测试时可以没执行一条语句都print时间看看。再改进。鉴于你的数据量非常大:
    c1 800多万
    ENTITY_DZ 暂时1000万数据
    ENTITY_link 暂时4000万数据应该考虑拆分任务,比如一个存储器处理一部分表,或者一部分任务。必要时服务器的计算能力也不够,可以考虑复制到其他服务器上去预先处理。这是我采用的方法。曾经写过一个存储器需要运行几个小时,在晚间,数据量也在千万条。
    也可以计算出一些中间结果,以减少存储器处理时的数量量。