2017-12-24 32 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; 

使用しての性能に差があります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_idAD_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

関連する問題