DB触发条件是否可以提高性能?

时间:2017-12-24 11:47:02

标签: oracle triggers database-performance database-trigger

我知道数据库触发条件只能是SQL表达式,并且不能包含子查询。但是,在触发器代码中,可以使用PL / SQL和子查询。我想也许这是因为使用触发条件,在适用的情况下,我们可以获得更好的性能(例如,可能保存SQL引擎和PL / SQL之间的上下文切换)。

例如,使用触发条件,我们有:

CREATE TRIGGER hr.salary_check
  BEFORE INSERT OR UPDATE OF salary, job_id ON hr.employees
  FOR EACH ROW
    WHEN (new.job_id <> 'AD_VP')
  BEGIN
    --pl/sql_block
  END;

并且没有使用触发条件我们有:

CREATE TRIGGER hr.salary_check
  BEFORE INSERT OR UPDATE OF salary, job_id ON hr.employees
  FOR EACH ROW
  BEGIN
    IF (new.job_id <> 'AD_VP') THEN
      --pl/sql_block
    END IF;
  END;

使用数据库触发条件之间的性能是否存在差异,以避免执行代码并在&#34; IF&#34;中使用相同的条件。触发器代码中的语句,以避免执行该代码?如果是这样,我很感激您对性能影响的评论。

1 个答案:

答案 0 :(得分:2)

只需做一个简单的测试和测量时间。

CREATE TABLE employees_0 AS
SELECT
    x * employee_id as employee_id,
    first_name,
    last_name,
    email,
    phone_number,
    hire_date,
    'AD_VP' As job_id,
    salary,
    commission_pct,
    manager_id,
    department_id
FROM
    employees
CROSS JOIN (
    SELECT level as x FROM dual CONNECT BY LEVEL <= 10000
) x
;
CREATE TABLE employees_1 AS SELECT * FROM employees_0;
CREATE TABLE employees_2 AS SELECT * FROM employees_0;

CREATE OR REPLACE TRIGGER hr.salary_check_1
  BEFORE INSERT OR UPDATE OF salary, job_id ON hr.employees_1
  FOR EACH ROW
    WHEN (new.job_id <> 'AD_VP')
  BEGIN
    :new.salary := :new.salary + 1;
  END;
/

CREATE TRIGGER hr.salary_check_2
  BEFORE INSERT OR UPDATE OF salary, job_id ON hr.employees_2
  FOR EACH ROW
  BEGIN
    IF (:new.job_id <> 'AD_VP') THEN
      :new.salary := :new.salary + 1;
    END IF;
  END;
/

现在:

set timing on;

update employees_0 set salary = salary + 2;

update employees_1 set salary = salary + 2;

update employees_2 set salary = salary + 2;

结果是:

1 070 000 rows updated.

Elapsed: 00:00:37.273

1 070 000 rows updated.

Elapsed: 00:00:37.232

1 070 000 rows updated.

Elapsed: 00:00:38.874

测试显示,在job_id列不同于AD_VP的表上执行UPDATE时,根本没有触发器的表与具有两种触发器版本的表之间的差异可以忽略不计对于所有行。

您可以自己对这些测试表执行其他测量 - 例如INSERT 1 mln。行,将值job_id更改为AD_VP并执行更新等。

我的系统是:

select * from v$version;

Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
PL/SQL Release 12.1.0.2.0 - Production
"CORE   12.1.0.2.0  Production"
TNS for 64-bit Windows: Version 12.1.0.2.0 - Production
NLSRTL Version 12.1.0.2.0 - Production