oracle - 操作 BULK COLLECT 数据时,存储过程中是否会发生上下文切换?

标签 oracle plsql

我在 11g 和 12c Oracle 系统上运行。我对即将编写的一些 PL/SQL 有疑问。我一直在进行广泛的研究,但我不太清楚答案,并希望从论坛中获得一些意见。我的主要目标是保持高水平的表现。在处理这些数据时,我试图避免上下文切换。

SP的目的是批量join来自2个不同表的一组数据,操作集合中的一组字段并将其写入不同Instance中的另一个表。我显然希望在 BULK 中做尽可能多的事情,但不确定在我完成它时,我是否会因为复杂的字段操作而以某种单行上下文切换结束。

详情如下:

声明一个将进行内部连接的游标。在 SELECT 中我想做一些数据操作。我想调用一个函数来执行此操作,因为在 select 语句中尝试执行此操作会非常困惑:

 CURSOR c1 is 
      SELECT DISTINCT A.ID,
        A.PT_NBR,
        A.PT_DT,
        A.PT_QTY,
      (COMPLX_CALC_FUNCTION(B.TR_TM,B.TR_CD ) nRESULT
      FROM PT_TABLE A
      INNER JOIN TRAN_TABLE B
        ON (A.PT_NBR           =  B.TRAN_NBR
        AND A.PT_DT         =  B.TRAN_DT
        AND A.PT_DT BETWEEN B.START_DT AND B.END_DT)
      WHERE A.ID = vID;

结果会是数十万或数百万条记录,所以我想批量处理

BEGIN
  OPEN c1;
  LOOP 
    FETCH c1 BULK COLLECT INTO vTable LIMIT 20000;

  ---body code

  -- trying to avoid additional manipulation of the data here but there may still be some

 FORALL indx IN vTable.FIRST .. vTable.LAST

...

 INSERT INTO Table2 VALUES vTable(indx); 

--ending stuff

;

COMPLX_CALC_FUNCTION 将获取输入并执行数学运算并调用其他函数,例如 NVL、SUM 和 CEIL。

所以,问题是……我是否会因为光标选择中的函数调用而进行上下文切换,或者我是否需要操作 SP 主体中的数据?另外,对于这种情况,我还需要考虑其他性能问题吗?我试图避免将数据转储到临时物理表中并对其进行操作,因为这似乎比在内存中进行操作要慢得多。感谢您的专家建议。

最佳答案

在内存循环中调用表中的函数?这将避免 SQL - PLSQL 上下文切换,它的成本要高得多,尤其是因为它将在每行返回时切换。 FORALL 循环可以替代内存中针对内存中的表的常规 for 循环。这应该仍然非常快。如果您想使用 FORALL 批量插入,您可以将插入从“for 循环”中取出,但对于额外的开销,我认为它不会有太大区别。

至于批量处理所有事情——我的建议是,对于“数亿”行——取决于表格的“厚度/厚度”——你肯定会破坏你的 PGA 并对数据库中的区域大小进行排序,除非你有一个非常善良的 DBA,他会为您提供所需的所有内存(值得怀疑)。作为一般规则,我尽量不要在内存中放置超过 2-5 百万行。

declare
  l_complex number; -- dont know the real datatype here??
BEGIN
  OPEN c1;
  LOOP 
    FETCH c1 BULK COLLECT INTO vTable LIMIT 20000;

  ---body code
  -- trying to avoid additional manipulation of the data here but there may     still be some

 FOR indx IN vTable.FIRST .. vTable.LAST loop
     l_complex : = COMPLX_CALC_FUNCTION(vtable(indx).TR_TM,vtable(indx).TR_CD );


    INSERT INTO Table2 VALUES vTable(indx); 
 end loop;

...



--ending stuff

; 

关于oracle - 操作 BULK COLLECT 数据时,存储过程中是否会发生上下文切换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35397747/

相关文章:

sql - 更新语句导致Oracle "No more data to read from socket"?

python - 将参数传递给 cursor.execute() 时在 pyodbc 中出现 UnicodeDecodeError,但在将参数直接写入字符串时却不会

sql - 插入查询给出 ORA-01722 : invalid number error

performance - hibernate v/s 存储过程或函数性能

sql - PL/SQL 性能优化 - 计算记录更改的总和与差值

oracle - PL/SQL : declare the list of numbers to be used in IN condition

sql - RedoLog 在 Oracle 中是如何工作的?

.net - 匿名 Oracle 参数?

oracle - 如何从 Oracle PL/SQL 访问 Subversion?

database - 将迭代的提取替换为 BULK COLLECT