日期:2014-05-16  浏览次数:20743 次

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

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

------解决方案--------------------
loop循环一张表,你可以把这张表只存进去1000条,看看时间是多少,然后再估算下时间,看看耗时,感觉像你上面那么估算肯定不准确。
另外可以用job实现存储过程的并行执行
------解决方案--------------------
不要把sql当作一步一步的数据处理过程。换个思路:把sql处理的数据当作一个集合,再来写sql,可能效率会高点。
------解决方案--------------------
首先,你根据每条查询的30、50毫秒来推测执行12次的时间是不准的,因为单条查询的时间包括硬解析、软解析时间,所以单次时间参考性不大。
其次,你可以在循环中批量commit,例如1万条commit一次,提升性能。
再次,优化你的查询、更新SQL,增加索引、使用merge等方法来提升更新性能。

下面给你个例子吧:
SQL code
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');

------解决方案--------------------
相对于loop 800万次的开销,单纯只优化查询时不行的,楼主应该考虑优化算法。
------解决方案--------------------
9#说的对,有时一条语句下去可能无任何结果,有时可能影响到非常多的记录。
如5楼的,可以存一些数据测试看看。测试时可以没执行一条语句都print时间看看。再改进。

鉴于你的数据量非常大:
c1 800多万
ENTITY_DZ 暂时1000万数据
ENTITY_link 暂时4000万数据

应该考虑拆分任务,比如一个存储器处理一部分表,或者一部分任务。必要时服务器的计算能力也不够,可以考虑复制到其他服务器上去预先处理。

这是我采用的方法。曾经写过一个存储器需要运行几个小时,在晚间,数据量也在千万条。
也可以计算出一些中间结果,以减少存储器处理时的数量量。