ktSystems Oracle & Technology Blog

Technology with a focus on Oracle & Java

  •  

    październik 2007
    P W Ś C P S N
         
    1234567
    891011121314
    15161718192021
    22232425262728
    293031  
  • Kategorie

Archiwum dla październik 16th, 2007

PL/SQL w Oracle 11g: Function Result Cache

Opublikował/a Tomasz Krajewski w dniu 16 październik 2007

Jedną z nowości w systemie zarządzania bazą danych Oracle 11g jest “Function Result Cache”. Podczas tworzenia funkcji w języku PL/SQL można dodać klauzulę ‘RESULT_CACHE’ określającą, że wynik funkcji ma być przechowywany w pamięci podręcznej (dokładniej w Shared Global Area, SGA) w celu ponownego wykorzystania w przyszłości. Przy ponownym wywołaniu funkcji dla tych samych argumentów co poprzednio wynik będzie pobrany z pamięci zamiast wyliczany jeszcze raz. Ma to wpływ głównie na czas wykonywania skomplikowanych i czasochłonnych funkcji.

Umieszczenie wyniku funkcji w obszarze SGA umożliwia dostęp do wyników dla wszystkich sesji – nie tylko dla sesji, która wykonała funkcję z klauzulą ‘RESULT_CACHE’.

Przykład:

CREATE OR REPLACE FUNCTION test_result_cache(p_employee_id IN NUMBER) RETURN NUMBER AS
v_salary NUMBER;
BEGIN
sys.dbms_lock.sleep(10);
select salary into v_salary from EMPLOYEES where employee_id = p_employee_id;
RETURN(v_salary);
END;
/
SQL> set timing on;
SQL> select test_result_cache(110) from dual;
TEST_RESULT_CACHE(110)
———————-
8200

Elapsed: 00:00:10.21
SQL> select test_result_cache(110) from dual;
TEST_RESULT_CACHE(110)
———————-
8200

Elapsed: 00:00:10.02

Teraz zmienimy deklarację funkcji dodając ‘RESULT_CACHE’:

SQL> CREATE OR REPLACE FUNCTION test_result_cache(p_employee_id IN NUMBER) RETURN NUMBER RESULT_CACHE AS
v_salary NUMBER;
BEGIN
sys.dbms_lock.sleep(10);
select salary into v_salary from EMPLOYEES where employee_id = p_employee_id;
RETURN(v_salary);
END;
/

SQL> select test_result_cache(110) from dual;
TEST_RESULT_CACHE(110)
———————-
8200

Elapsed: 00:00:10.10
SQL> select test_result_cache(110) from dual;
TEST_RESULT_CACHE(110)
———————-
8200

Elapsed: 00:00:00.00

Widać, że pierwsze wywołanie nadal zajmuje 10 sekund, jednak przy kolejnym wartość funkcji pobierana jest z pamięci a nie wyliczana ponownie.

W przypadku, gdy funkcja podczas wyznaczania wartości korzysta z tabel lub perspektyw warto wykorzystać dodatkowo klauzulę ‘RELIES_ON’. Umożliwia ona uniknięcie błędnych wyników w przypadku, gdy na tabeli wykonywane są operacje DML. Kolejny przykład:

SQL> update EMPLOYEES set salary = 16000 where employee_id = 110;

1 row updated.

Elapsed: 00:00:00.20
SQL> select test_result_cache(110) from dual;
TEST_RESULT_CACHE(110)
———————-
8200

Elapsed: 00:00:00.01

Aby usunąć błąd z niewłaściwą wartością dodajemy RELIES_ON (EMPLOYEES):

SQL> CREATE OR REPLACE FUNCTION test_result_cache(p_employee_id IN NUMBER) RETURN NUMBER RESULT_CACHE RELIES_ON (EMPLOYEES) AS
2 v_salary NUMBER;
BEGIN
sys.dbms_lock.sleep(10);
select salary into v_salary from EMPLOYEES where employee_id = p_employee_id;
RETURN(v_salary);
END;
/

SQL> select test_result_cache(110) from dual;
TEST_RESULT_CACHE(110)
———————-
16000

Elapsed: 00:00:10.04
SQL> select test_result_cache(110) from dual;
TEST_RESULT_CACHE(110)
———————-
16000

Elapsed: 00:00:00.01
SQL> update EMPLOYEES set salary = 20000 where employee_id = 110;

1 row updated.

Elapsed: 00:00:00.01
SQL> select test_result_cache(110) from dual;
TEST_RESULT_CACHE(110)
———————-
20000

Elapsed: 00:00:10.01

Innym ciekawym przykładem wykorzystania RESULT_CACHE jest funkcja wyznaczająca wartość n-tego wyrazu ciągu fibonnaciego:

CREATE OR REPLACE FUNCTION fibonacci (n NUMBER)
RETURN NUMBER RESULT_CACHE IS
BEGIN
IF (n =0) OR (n =1) THEN
RETURN 1;
ELSE
RETURN fibonacci(n - 1) + fibonacci(n - 2);
END IF;
END;
/

Dla funkcji z klauzula ‘RESULT_CACHE’ istnieją pewne ograniczenia – przede wszystkim nie może ona mieć parametrów typu OUT i IN OUT. Dodatkowo zarówno parametry jak i wartość wynikowa nie mogą być typu BLOB, CLOB, NCLOB, REF CURSOR, Collection (tylko parametry), Object, Record(w tym przypadku Record jest dopuszczalny dla wartości wynikowej pod warunkiem, że nie zawiera w sobie innych zabronionych typów).

Administrator Oracle 11g w celu zarządzania ‘RESULT_CACHE’ może korzystać:

* parametry inicjalizacyjne (RESULT_CACHE_MAX_SIZE, RESULT_CACHE_MAX_RESULT)
* pakiet DBMS_RESULT_CACHE
* perspektywy: [G]V$RESULT_CACHE_STATISTICS, [G]V$RESULT_CACHE_MEMORY, [G]V$RESULT_CACHE_OBJECTS, [G]V$RESULT_CACHE_DEPENDENCY

Korzystając z klauzuli ‘RESULT_CACHE’ musimy pamiętać, aby nie modyfikowała ona stanu bazy danych (brak operacji DML i DDL) i nie modyfikowała sesji – od wykonania lub niewykonania (czyli pobrania wartości zwracanej z SGA) tej funkcji nie mogą więc zależeć żadne procesy biznesowe.

Linki zewnętrzne:

Using the Cross-Session PL/SQL Function Result Cache

Opublikowany w Oracle 11g | Otagowane: | Zostaw Komentarz »