2

我有一个 10 行的参数表。称为参数表。在我的 PL/SQL 过程中,我循环了 200 万条记录。并且每次也查询这个参数表。

我想将此参数表加载到内存中并减少 I/O 进程。

做这个的最好方式是什么?

 FOR cur_opt
  IN (SELECT customer_ID,
             NVL (customer_type, 'C') cus_type
        FROM invoice_codes 
       WHERE ms.invoice_type='RT') 
LOOP
  ....
  ...

  Select data From parameter_table Where cus_type = cur_opt.cus_type AND cr_date < sysdate ;  -- Where clause is much complex than this..

....
...
END LOOP;
4

3 回答 3

3

您可以将其加入主查询:

select customer_id, data
from   parameter_table t, invoice_codes c
where  t.cus_type = nvl(c.customer_type, 'C')
and    t.cr_date < sysdate

但是,如果您有 200 万条记录invoice_codes,则加入参数表是您最不关心的问题 - 循环执行此操作将需要一些时间(并且可能是您的 I/O 问题的真正原因)。

于 2013-03-04T20:28:26.557 回答
1

我认为您可以更改查询,加入参数表,因此无需在循环内点击 select 语句。(就像@Chris Saxon 的解决方案一样)

但作为使用兑现数据的一种方式,您可以填写一个字典,如数组,然后在必要时引用它
这样的事情可能会有所帮助:

您必须Fill_parameters_cash在启动主进程之前调用并调用get_parameter 以获取数据,调用的输入参数get_parameter是字典键

TYPE ga_parameter_t IS TABLE OF parameter_table%ROWTYPE INDEX BY BINARY_INTEGER;
ga_parameter ga_parameter_t;

procedure Fill_parameters_cash is
  begin 
    ga_parameter.DELETE;
    SELECT * BULK COLLECT
    INTO   ga_parameter
    FROM   parameter_table;    
end Fill_parameters_cash;

FUNCTION get_parameter(cus_type invoice_codes.cus_type%TYPE,
                                 is_fdound    OUT BOOLEAN)
    RETURN parameter_table%ROWTYPE IS
    result_value parameter_table%ROWTYPE;

    pos NUMBER;
  BEGIN
    result_value := NULL;
    is_fdound := FALSE;
    IF cus_type IS NULL THEN
      RETURN NULL;
    END IF;  

    pos := ga_parameter.FIRST;
    WHILE pos IS NOT NULL
    LOOP
      EXIT WHEN ga_parameter(pos).cus_type  = cus_type;
      pos := ga_parameter.NEXT(pos);
    END LOOP; 
   IF pos IS NOT NULL THEN
      is_fdound    := TRUE;
      result_value := ga_parameter(pos);
    END IF;  
    RETURN result_value;
  END get_parameter; 
于 2013-03-05T06:55:52.503 回答
0

我猜循环浏览一百万条记录已经引起了问题。不太确定这个参数表查找如何真正恶化它。

无论如何,如果这确实是您可以采用的唯一方法,那么您可以在游标声明中进行内部或外部联接。

----
 FOR cur_opt
  IN (SELECT customer_ID,
             NVL (customer_type, 'C') cus_type
        FROM invoice_codes codes,
             parameter_table par 
       WHERE ms.invoice_type='RT'
         and codes.cus_type = par.cus_type -- (or an outer join) maybe?
      ) loop
..........
于 2013-03-04T20:29:11.760 回答