Oracle FORALL不会提高性能

时间:2014-12-30 11:01:13

标签: oracle oracle11g oracle11gr2

我正在使用oracle FORALL构造来提高PL / SQL块的性能。我正在写下FORALL的'之前'和'之后'代码 -

BEFORE:

 FOR employee_rec IN (SELECT employee_id
                      FROM employees
                      WHERE department_id =
                      increase_salary_prc.p_department_id_in)
 LOOP
    check_eligibility_prc (employee_rec.employee_id, l_eligible);

    IF l_eligible THEN
      UPDATE employees emp
      SET emp.salary = emp.salary + emp.salary * increase_salary_prc.p_increase_pct_in
      WHERE emp.employee_id = employee_rec.employee_id;
    END IF;
  END LOOP;

AFTER:

 TYPE employee_ids_t IS TABLE OF employees.employee_id%TYPE INDEX BY PLS_INTEGER; 
 l_employee_ids   employee_ids_t;
 l_eligible_ids   employee_ids_t;

 BEGIN

 SELECT employee_id
 BULK COLLECT INTO l_employee_ids
 FROM employees
 WHERE department_id = increase_salary_prc.p_department_id_in;

 FOR indx IN 1..l_employee_ids.COUNT 
 LOOP
    check_eligibility_prc (l_employee_ids(indx),
                           l_eligible);

    IF l_eligible THEN
      l_eligible_ids(l_eligible_ids.COUNT + 1) := l_employee_ids(indx);
    END IF;  
 END LOOP;

 FORALL indx IN 1..l_eligible_ids.COUNT
      UPDATE employees emp
      SET emp.salary = emp.salary + emp.salary * increase_salary_prc.p_increase_pct_in
      WHERE emp.employee_id = l_eligible_ids(indx);

其他信息 -

员工总数记录--20000 有2个部门--15和16,每个部门包含10000个记录。程序仅针对部门15运行。在10000中,符合更新条件的是5000。

check_eligibility_prc的代码 -

SELECT eligible
INTO l_eligible
FROM EMPLOYEES
WHERE employee_id = p_emp_id;

IF l_eligible = 'Y' THEN
   p_eligible := TRUE;
ELSE
   p_eligible := FALSE;
END IF;

在'之前'代码中 - 1. for循环运行10000次 2.内部循环中的'IF'是真实的5000次。因此更新查询运行5000次。

在'之后'代码中 - 1.循环运行10000次。 2.内部循环中的'IF'是真实的5000次。 3. l_eligible_ids insidd FORALL循环包含5000条要更新的记录

使用'before'块,代码运行637.42秒。但令人惊讶的是,“后”代码花费了极少的额外时间。这需要637.545秒。

任何人都可以就此为何发生任何指示吗? BULK COLLECT和FORALL假设减少了所花费的时间。相反,它增加了执行块的时间。

1 个答案:

答案 0 :(得分:1)

尝试

update employees emp
set emp.salary = emp.salary + emp.salary * increase_salary_prc.p_increase_pct_in
where emp.department_id = increase_salary_prc.p_department_id_in
and emp.eligible = 'Y';

它看起来完全一样但速度会快得多。

P.S。十分钟是这些价值的令人难以置信的低速。即使有10 000个不必要的选择。