2017-12-24 39 views
1

DB 트리거 조건은 SQL식이 될 수 있으며 하위 쿼리를 포함 할 수 없다는 것을 알고 있습니다. 그러나 트리거 코드 내에서 PL/SQL 및 하위 쿼리를 사용할 수 있습니다. 가능한 경우 트리거 조건을 사용하면 더 나은 성능을 얻을 수 있다고 생각했습니다 (예 : SQL 엔진과 PL/SQL 간의 컨텍스트 전환이 저장되는 경우).DB 트리거 조건이 성능을 향상 시킵니까?

예를 들어, 트리거 조건을 사용하여 우리가 가진 것 :

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; 

사용 a 사이의 성능 차이가 있습니다 DB의 트리거 조건은 코드의 실행을 피하고 그 코드의 실행을 피하기 위해 트리거 코드의 "IF"문 안에서 같은 조건을 사용하기 위해서입니까? 그렇다면 성능에 미치는 영향에 대한 의견을 보내 주시면 감사하겠습니다.

답변

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 

테스트는 differen 무시할 수 있다는 것을 보여줍니다 모든 행에 대해 job_id 열이 AD_VP이 아닌 테이블에서 UPDATE를 수행하는 동안 트리거가없는 테이블과 두 버전의 트리거가있는 테이블 사이의 차이입니다.

이러한 테스트 테이블에 대해 다른 조치를 직접 수행 할 수 있습니다 (예 : INSERT 1 mln). 행, AD_VPjob_id의 값을 변경하고 업데이트 등


내 시스템이 수행

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 
+0

감사합니다. 나는 오라클이 이것에 관해서 어떤 것을 말하고 있을지도 모른다고 생각하고 있었고, 그래서 이것에 대한 좀 더 일반적인 지식을 가지고있다. 가독성 문제와는 별도로 트리거 조건의 목적이 무엇인지 알지 못합니다. 트리거 코드 내에서 동일한 작업을 수행 할 수 있으며 트리거 조건에서 수행 할 수있는 작업에 제한이있는 이유는 무엇입니까? 감사. – shwartz