Oracle
 sql >> база данни >  >> RDS >> Oracle

Консолидирайте няколко задействания на Oracle. Има ли влияние върху производителността?

Сега направих сравнителен анализ на тази ситуация и стигнах до заключението, че има значителна загуба на производителност, най-вероятно поради превключване на контекста на PL/SQL, при добавяне на 1 тригер. Загубата е с фактор 8 в моя бенчмарк. Добавянето на втори „съвместим“ тригер обаче вече няма значително въздействие. Под „съвместим“ имам предвид и двата тригера винаги да се задействат при едно и също събитие в произволен ред.

Така че заключавам, че най-вероятно има само 1 SQL -> PL/SQL превключвател на контекст за всички тригери

Ето бенчмарка:

Създаване на таблица

-- A typical table with primary key, creation/modification user/date, and 
-- other data columns
CREATE TABLE test(
  id number(38)    not null, -- pk
  uc varchar2(400) not null, -- creation user
  dc date          not null, -- creation date
  um varchar2(400),          -- modification user
  dm date,                   -- modification date
  data number(38)
);

... и последователност

CREATE SEQUENCE s_test;

Типичен идентификатор на настройка на тригер, потребител/дата на създаване/модифициране

CREATE OR REPLACE TRIGGER t_test BEFORE INSERT OR UPDATE
  ON test
  FOR EACH ROW
BEGIN
  IF inserting THEN
    SELECT s_test.nextval INTO :new.id FROM dual;

    :new.uc := USER;
    :new.dc := SYSDATE;
    :new.um := NULL;
    :new.dm := NULL;
  END IF;
  IF updating THEN
    :new.um := USER;
    :new.dm := SYSDATE;
    :new.uc := :old.uc;
    :new.dc := :old.dc;
  END IF;
END t_test;

Вмъкване на 1000, 10000, 100000 записа

declare
  procedure run (limit number) is
    t timestamp;
  begin
    t := systimestamp;

    insert into test (data)
    select level from dual connect by level < limit;

    dbms_output.put_line(to_char(systimestamp - t));

    rollback;
  end;
begin
  run(1000);
  run(10000);
  run(100000);
end;

Резултати

-- ------------------------------------
-- +000000000 00:00:00.086603000
-- +000000000 00:00:00.844333000
-- +000000000 00:00:08.429186000
-- ------------------------------------

Друг „съвместим“ тригер (редът на изпълнение е без значение)

CREATE OR REPLACE TRIGGER t_test_other BEFORE INSERT OR UPDATE
  ON test
  FOR EACH ROW
BEGIN
  :new.data := 42;
END t_test_other;

Резултати от друго изпълнение на тестовия скрипт

-- ------------------------------------
-- +000000000 00:00:00.088551000
-- +000000000 00:00:00.876028000
-- +000000000 00:00:08.731345000
-- ------------------------------------

Деактивирайте тригерите

alter trigger t_test disable;
alter trigger t_test_other disable;

Изпълнете малко по-различен тестов скрипт

declare
  procedure run (limit number) is
    t timestamp;
  begin
    t := systimestamp;

    insert into test (id, uc, dc, data)
    select s_test.nextval, user, sysdate, level from dual 
    connect by level < limit;

    dbms_output.put_line(to_char(systimestamp - t));

    rollback;
  end;
begin
  run(1000);
  run(10000);
  run(100000);
end;

Резултати

-- ------------------------------------
-- +000000000 00:00:00.012712000
-- +000000000 00:00:00.104903000
-- +000000000 00:00:01.043984000
-- ------------------------------------


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да изтрия редове с двупосочни зависимости?

  2. oracle sql изберете синтаксис с клауза GROUP BY и HAVING

  3. Пролетна поддръжка на JDBC и голям набор от данни

  4. Непоследователно транспониране

  5. Транспониране на ред колона в Oracle Sql