Oracle 11g nowe cechy w strojeniu wydajności i tworzeniu aplikacji dla bazy danych



Podobne dokumenty
Pakiety podprogramów Dynamiczny SQL

Język PL/SQL. Rozdział 5. Pakiety podprogramów. Dynamiczny SQL

Wyzwalacz - procedura wyzwalana, składowana fizycznie w bazie, uruchamiana automatycznie po nastąpieniu określonego w definicji zdarzenia

w PL/SQL bloki nazwane to: funkcje, procedury, pakiety, wyzwalacze

Procedury składowane. Funkcje vs. procedury Funkcja. Procedura. zazwyczaj ma parametry tylko typu IN; można wywoływać z poziomu

Oracle11g: Programowanie w PL/SQL

PODSTAWY BAZ DANYCH 13. PL/SQL

Wyzwalacze. do automatycznego generowania wartości kluczy głównych. Składnia instrukcji tworzacej wyzwalacz

Bloki anonimowe w PL/SQL

Język PL/SQL Procedury i funkcje składowane

Cheatsheet PL/SQL Andrzej Klusiewicz 1/9

Instrukcja podwaja zarobki osób, których imiona zaczynają się P i dalsze litery alfabetu zakładamy, że takich osbób jest kilkanaście.

Używany kiedy pełna treść instrukcji SQL jest nieznana przed uruchomieniem programu.

PL/SQL. Zaawansowane tematy PL/SQL

Pakiety są logicznymi zbiorami obiektów takich jak podprogramy, typy, zmienne, kursory, wyjątki.

Procedury i funkcje składowane

Oracle PL/SQL. Paweł Rajba.

Procedury wyzwalane. (c) Instytut Informatyki Politechniki Poznańskiej 1

DECLARE VARIABLE zmienna1 typ danych; BEGIN

Blaski i cienie wyzwalaczy w relacyjnych bazach danych. Mgr inż. Andrzej Ptasznik

KOLEKCJE - to typy masowe,zawierające pewną liczbę jednorodnych elementów

Wyzwalacze. Anna Fiedorowicz Bazy danych 2

15. Funkcje i procedury składowane PL/SQL

Język PL/SQL Pakiety podprogramów

Oracle PL/SQL. Paweł Rajba.

Oracle PL/SQL. Paweł Rajba.

DECLARE <nazwa_zmiennej> typ [(<rozmiar> )] [ NOT NULL ] [ { := DEFAULT } <wartość> ];

Oracle10g: Programowanie w PL/SQL

Zaawansowane bazy danych i hurtownie danych semestr I

Oracle11g: Wprowadzenie do SQL

Tworzenie widoku CREATE OR REPLACE VIEW [nazwa_widoku] AS SELECT [nazwy_kolumn] FROM [nazwa_tablicy];

Funkcje w PL/SQL Funkcja to nazwany blok języka PL/SQL. Jest przechowywana w bazie i musi zwracać wynik. Z reguły, funkcji utworzonych w PL/SQL-u

ORACLE (Wykład 1) aragorn.pb.bialystok.pl/~aonisko. Typy rozproszonych baz danych. Systemy klient-serwer. Klient-serwer: Przykład

Materiały. Technologie baz danych. Plan wykładu Kursory. Wykład 5: Kursory jawne. Podprogramy. Kursory jawne. Kursory niejawne

Programowanie w SQL procedury i funkcje. UWAGA: Proszę nie zapominać o prefiksowaniu nazw obiektów ciągiem [OLIMP\{nr indeksu}] Funkcje użytkownika

Kowalski Marcin Wrocław, dn Jaśkiewicz Kamil Bazy Danych 1 Podstawy Projekt Temat: Baza danych do zarządzania projektami

Bazy danych wykład dwunasty PL/SQL, c.d. Konrad Zdanowski ( Uniwersytet Kardynała Stefana Bazy danych Wyszyńskiego, wykładwarszawa)

Język PL/SQL. Rozdział 4. Procedury i funkcje składowane

Tworzenie raportów XML Publisher przy użyciu Data Templates

Składowane procedury i funkcje

Plan wykładu BAZY DANYCH II WYKŁAD 3. Zasięg zmiennych. Zasięg zmiennych

Oracle PL/SQL. Paweł Rajba.

Podprogramy. Rozdział 11 Procedury i funkcje składowane

Oracle PL/SQL. Paweł Rajba.

PL/SQL. Zaawansowane tematy PL/SQL. Piotr Medoń

1 Wprowadzenie do bloków nazwanych 1. 2 Parametry 2. 3 Procedury i funkcje 3. 4 Pakiety 6. 5 Podsumowanie Źródła 10

Paweł Rajba

Wykład 5 funkcje i procedury pamiętane widoki (perspektywy) wyzwalacze

SQL (ang. Structured Query Language)

Język PL/SQL. Rozdział 6. Procedury wyzwalane

Hurtownia Świętego Mikołaja projekt bazy danych

Plan wykładu BAZY DANYCH II WYKŁAD 7. Pakiety. Zalety pakietów

Optymalizacja poleceń SQL Wprowadzenie

Systemy GIS Tworzenie zapytań w bazach danych

SQL 4 Structured Query Lenguage

Procedury wyzwalane. Rozdział 13. Procedury wyzwalane. Cele stosowania procedur wyzwalanych. Definiowanie procedury wyzwalanej DML

Wprowadzenie do projektowania i wykorzystania baz danych Relacje

BAZY DANYCH Cz III. Transakcje, Triggery

Zarządzanie bazą danych. Bazy Danych i Systemy informacyjne Wykład 4. Piotr Syga

BAZA DANYCH SIECI HOTELI

E.14 Bazy Danych cz. 18 SQL Funkcje, procedury składowane i wyzwalacze

Administracja i programowanie pod Microsoft SQL Server 2000

1. Wyzwalacze BD (ang. triggers)

Bazy danych, 4. wiczenia

Zarządzanie obiektami bazy danych Oracle11g

Optymalizacja poleceń SQL Statystyki

Zarządzanie obiektami bazy danych Oracle11g

Kursory i wyjątki. (c) Instytut Informatyki Politechniki Poznańskiej 1

Cele. Definiowanie wyzwalaczy

Plan wykładu BAZY DANYCH II WYKŁAD 9. Dynamiczny SQL. Dynamiczny SQL

Plan wykładu BAZY DANYCH II WYKŁAD 2. Bloki. Struktura bloku

Kolekcje Zbiory obiektów, rodzaje: tablica o zmiennym rozmiarze (ang. varray) (1) (2) (3) (4) (5) Rozszerzenie obiektowe w SZBD Oracle

Administracja i programowanie pod Microsoft SQL Server 2000

Plan bazy: Kod zakładający bazę danych: DROP TABLE noclegi CASCADE; CREATE TABLE noclegi( id_noclegu SERIAL NOT NULL,

Administracja i programowanie pod Microsoft SQL Server 2000

strukturalny język zapytań używany do tworzenia i modyfikowania baz danych oraz do umieszczania i pobierania danych z baz danych

SQL w języku PL/SQL. 2) Instrukcje języka definicji danych DDL DROP, CREATE, ALTER, GRANT, REVOKE

PHP: bazy danych, SQL, AJAX i JSON

SQL :: Data Definition Language

1 Kursory 1. 2 Wyjątki Wyjątki predefiniowane Wyjątki niezdefiniowane wcześniej Definiowanie własnych wyjątków...

Deklarowanie kursora

Systemy baz danych 2 laboratorium Projekt zaliczeniowy

SYSTEM INFORMATYCZNY KS-SEW

Język SQL, zajęcia nr 1

1: 2: 3: 4: 5: 6: 7: 8: 9: 10:

CREATE USER

Microsoft SQL Server Podstawy T-SQL

Wykład 8. SQL praca z tabelami 5

Bazy danych. Wykład IV SQL - wprowadzenie. Copyrights by Arkadiusz Rzucidło 1

Deklarowanie kursora. CURSOR nazwa [ ( param1 typ1 [,param2 typ2]... ) ] [RETURN typ zwracany] IS zapytanie SQL;

Przykład 3 Zdefiniuj w bazie danych hurtownia_nazwisko przykładową funkcję użytkownika fn_rok;

ZASTOSOWANIE PROCEDUR, FUNKCJI I PAKIETÓW

Oracle PL/SQL. Paweł Rajba.

BAZY DANYCH W APLIKACJACH SIECIOWYCH

Plan wykładu BAZY DANYCH II WYKŁAD 8. Wyzwalacze. Wyzwalacze

Bloki anonimowe w PL/SQL

Plan wykładu BAZY DANYCH II WYKŁAD 4. Co to jest kursor? Rodzaje kursorów

Programowanie MSQL. show databases; - pokazanie jakie bazy danych są dostępne na koncie

Trigger jest obiektem związanym z tablicą, który aktywuje się gdy do tablicy następuje odpowiednie zapytanie.

Transkrypt:

XIV Konferencja PLOUG Szczyrk Październik 2008 Oracle 11g nowe cechy w strojeniu wydajności i tworzeniu aplikacji dla bazy danych Kamil Stawiarski Royal Software Sp. z o.o. Abstrakt. Baza danych Oracle 11g dostarcza nie tylko wielu nowych funkcjonalności lecz także rozwiązuje problemy, które do tej pory stanowiły zmartwienie deweloperów. Dzięki nowym opcjom obsługi triggerów, tabelom read-only, ulepszonej obsłudze wyrażeń regularnych oraz kilku kosmetycznym poprawkom zaimplementowanym w nowej wersji bazy danych deweloperzy odczują poprawę komfortu programowania. Wygodne są nowe możliwości optymalizacji wydajności kodu, testowania aplikacji, niewidzialne indeksy, ulepszona natywna kompilacja PL/SQL, czy bufor Result Cache. Informacja o autorze. Kamil Stawiarski zajmuje stanowisko dyrektora technologicznego w firmie Royal Software. Od kilku lat zajmuje się bazą Oracle, zarówno od strony deweloperskiej jak również administratorskiej. Dzięki zdobytej wiedzy oraz doświadczeniom prowadzi konsultacje oraz wykłady na szkoleniach autoryzowanych oraz konsultacjach dla Partnerów Oracle.

Baza danych Oracle 11g dostarcza wielu nowych funkcjonalności oraz rozwiązań problemów, które do tej pory stanowiły zmorę deweloperów. Dzięki nowym opcjom obsługi triggerów, tabelom read-only, ulepszoną obsługą wyrażeń regularnych oraz kilku kosmetycznym poprawkom zaimplementowanym w nowej wersji bazy danych odczujemy poprawę komfortu programowania. Wygodą stały się też nowe możliwości optymalizacji wydajności kodu, oraz testowania aplikacji. Niewidzialne indexy, ulepszona natywna kompilacja PL/SQL, czy bufor Result Cache powinny pozytywnie wpłynąć na nasz codzienny kontakt z bazą Oracle. Przyjrzyjmy się zatem kilku ciekawszym właściwościom najnowszej bazy danych firmy Oracle. SQL*Plus Najprostszym i najprzyjemniejszym narzędziem do obsługi bazy danych Oracle zawsze był SQL*Plus narzędzie tekstowe o przyjaźnie migającym kursorku. Szczerze mówiąc myślałem, że w Oracle 11g ktoś wpadnie na pomysł, żeby dostarczać to narzędzie z jakże prostą, acz przyjemną opcją historii poleceń, czy dopełniania składni, jednak moje nadzieje okazały się płonne. Zamiast tego otrzymaliśmy produkt wzbogacony o kilka zacnych funkcjonalności, które w ostatecznym rozrachunku mogą być nam wielce przydatne. set errorlogging on całkiem pożyteczna opcja, która upraszcza wykrywanie błędów w skryptach; wiele razy się zdarzało, że pisałem skrypt administracyjny, który powstawał w celu wykonania określonych zadań migracyjnych, aplikacyjnych lub po prostu dla symulacji obciążenia testowej bazy danych. Wiele razy zdarzyło się, że skrypt generował serię błędów, które łatwo było przeoczyć, jeśli nie napisało się do nich własnej obsługi. Dzięki temu nowemu poleceniu, wszystkie błędy powstałe w wyniku poleceń wydawanych w SQL*Plus zostają zapisane do tabeli o nazwie SPERRORLOG. Znajdziemy tam informacje o użytkowniku, poleceniu oraz komunikacie błędu zwróconego przez Oracle. Tabela jest zwykłą tabelą, podlegającą normalnym zasadom tranzakcyjności naturalnie oznacza to, że jeżeli po serii powstałych błędów nasza sesja ulegnie brutalnemu zamknięciu, nie zobaczymy cennych informacji, mogących naprowadzić nas na stosowny trop. Nie mniej jednak jest to opcja, która może w szczególnych przypadkach znacznie ułatwić proces poszukiwania błędów w skryptach. SQL> set errorlogging on

SQL> desc sperrorlog Nazwa Wartosc NULL? Typ ----------------------------- -------- -------------------- USERNAME VARCHAR2(256) TIMESTAMP TIMESTAMP(6) SCRIPT VARCHAR2(1024) IDENTIFIER VARCHAR2(256) MESSAGE CLOB STATEMENT CLOB SQL> l 1 select username, timestamp, statement, message 2 from sperrorlog 3* where rownum=1 SQL> / US TIMESTAMP STATEMENT MESSAGE -- ------------------------------ -------------------- ------------------------------------------------------------------------------------------ HR 08/09/20 13:49:52,000000 delete employees ORA-12081: operacja aktualizacji nie jest dozwolona dla PL/SQL Podstawowym językiem tworzenia oprogramowania na bazie danych Oracle od zawsze był PL/SQL. Oracle 11g dostarcza kilka ciekawych rozwiązań, którymi warto się przyjrzeć rozważając migracje dotychczasowych aplikacji. trigger following clause wiele razy w swojej karierze zmuszony byłem do aktualizacji bieżących rozwiązań opartych na triggerach ze względu na ewolucję procesów biznesowych aplikacji. Pociągało to za sobą konieczność modyfikacji kodu konkretnego triggera dla zachowania sekwencyjności wykonywanych operacji. Z punktu widzenia dbania o kod i utrzymywania go w należytym porządku oraz zgodnie ze wszelkimi dobrymi praktykami programowania należałoby wówczas stworzyć kolejny trigger przeznaczony do obsługi nowej funkcjonalności. W poprzednich wersjach bazy tego typu rozwiązanie było wykluczone ze względu na nieprzewidywalność kolejności uruchamiania dwóch takich samych triggerów. Baza danych Oracle 11g pozwala nam na wyspecyfikowanie klauzuli, w której możemy określić kolejność uruchamiania stworzonych triggerów. CREATE OR REPLACE TRIGGER TRIG_GEN_PASS BEFORE INSERT ON EMPLOYEES FOR EACH ROW BEGIN :new.default_pass := to_char(:new.hire_date, 'YYYYMMDY') upper(substr(:new.first_name, 1, 2)) initcap(substr(:new.last_name, 1, 2)); END; / CREATE OR REPLACE

TRIGGER TRIG_HASH_PASS BEFORE INSERT ON EMPLOYEES FOR EACH ROW follows trig_gen_pass BEGIN :new.default_pass := DBMS_OBFUSCATION_TOOLKIT.MD5(INPUT_STRING=>:new.default_pass); END; / W pierwszym triggerze zostało wygenerowane standardowe hasło nowo dodawanego pracownika. Trigger nr 2 natomiast zawiera prosty kod hashujący wygenerowane wcześniej hasło. W powyższym przykładzie moglibyśmy dodać między tymi dwoma triggerami jeszcze jeden (w środku), którego funkcjonalność polegałaby na przesłaniu e-mailem wygenerowanego hasła. Dzięki takiemu rozbiciu kodu mogę łatwiej zarządzać poszczególnymi etapami obsługi dodania nowego pracownika. Mogę również wyłączać poszczególne etapy ( alter trigger disable clause ), dla celów deweloperskich, lub testowych. Compound trigger jest to nowość w Oracle 11g, dla której bez problemu znajdzie zastosowanie każdy deweloper PL/SQL. Wiele razy, aby zaimplementować jakąś funkcjonalność była potrzeba stworzenia kilku triggerów before statement, after each row i after statement. W dodatku, każda z faz zależała od poprzedniej w bezpośredni sposób. Jeżeli był wymagany przepływ danych między triggerami, musieliśmy kombinować ze zmiennymi pakietowymi lub innymi sposobami zachowywania spójności między poszczególnymi wywołaniami. Obecnie możemy stworzyć jeden trigger, w którym da się wyszczególnić określone sekcje: przed wykonaniem polecenia, przed wykonaniem poszczególnych wierszy, po wykonaniu poszczególnych wierszy, po wykonaniu polecenia no i sekcja deklaracyjna triggera. Tego typu triggery mogą działać oczywiście tylko przy poleceniach DML. Na pierwszy rzut oka widać jednak ich przydatność konstrukcja pozwala poprawić wydajność implementacji określonych funkcjonalności, jak również usprawnia zarządzanie i obsługę kodu. CREATE OR REPLACE TRIGGER Check_Employee_Salary_Raise FOR UPDATE OF Salary ON Employees COMPOUND TRIGGER Ten_Percent CONSTANT NUMBER := 0.1; TYPE Salaries_t IS TABLE OF Employees.Salary%TYPE; Avg_Salaries Salaries_t; TYPE Department_IDs_t IS TABLE OF Employees.Department_ID%TYPE; Department_IDs Department_IDs_t; TYPE Department_Salaries_t IS TABLE OF Employees.Salary%TYPE INDEX BY VARCHAR2(80);

Department_Avg_Salaries Department_Salaries_t; BEFORE STATEMENT IS BEGIN SELECT AVG(e.Salary), NVL(e.Department_ID, -1) BULK COLLECT INTO Avg_Salaries, Department_IDs FROM Employees e GROUP BY e.department_id; FOR j IN 1..Department_IDs.COUNT() LOOP Department_Avg_Salaries(Department_IDs(j)) := Avg_Salaries(j); END LOOP; END BEFORE STATEMENT; AFTER EACH ROW IS BEGIN IF :NEW.Salary - :Old.Salary > Ten_Percent*Department_Avg_Salaries(:NEW.Department_ID) THEN Raise_Application_Error(-20000, 'Raise too big'); END IF; END AFTER EACH ROW; END Check_Employee_Salary_Raise; Powyższy przykład został zaczerpnięty z dokumentacji do bazy Oracle11g. Widać na nim użycie compound trigger w celu uniknięcia mutowania tabeli nie możemy dać podwyżki pracownikowi, jeśli przekracza ona 10% wartości średnich zarobków w departamencie, w którym pracuje. Function Result Cache funkcjonalność ta jest przydatna, gdy odwołujemy się często do funkcji, która zwraca zazwyczaj ten sam wynik, dla tych samych parametrów wejściowych. Możemy określić, żeby wynik funkcji został zapisany w buforze, dzięki temu każde kolejne wywołanie funkcji z określonymi parametrami będzie pobierało wynik z bufora. Parametr relies_on określa tabele, z których korzysta funkcja w swoim ciele jeżeli zawartość tabeli ulegnie zmianie, zbuforowana zawartość ulegnie inwalidacji. Dokładniejszy opis działania bufora Result Cache zostanie opisana w późniejszej części tego dokumentu. Jeżeli chcemy użyć w funkcji opcji function result cache, musimy trzymać się określonych restrykcji: Funkcja nie może być wywoływana z prawami wywołującego Funkcja nie może być użyta w bloku anonimowym Funkcja nie może posiadać parametrów OUT Funkcja nie może przyjmować parametrów złożonych Funkcja nie może zwracać złożonego typu danych CREATE OR REPLACE FUNCTION F_GET_STATUS(p_dept_name departments.department_name%type) RETURN VARCHAR2

result_cache relies_on(employees, departments) as v_sal employees.salary%type; v_ret VARCHAR2(3); BEGIN select avg(salary) into v_sal from employees e, departments d where e.department_id= d.department_id and d.department_name= p_dept_name; if v_sal > 8600 then v_ret := 'YES'; elsif v_sal is null then v_ret := 'NOT'; raise no_data_found; else v_ret := 'NO'; end if; return v_ret; exception when no_data_found then dbms_output.put_line('nie ma takiego departmentu jak ' p_dept_name); return v_ret; END F_GET_STATUS; / SQL> select f_get_status('it') from dual; 2 F_GET_STATUS('IT') -------------------------- NO SQL> select status 2 from v$result_cache_objects 3 where name like '%F_GET_STATUS%' 4 and TYPE='Result' 5 / STATUS --------- Published SQL> update departments 2 set department_name=initcap(department_name); 27 wierszy zostalo zmodyfikowanych. SQL> commit; Zatwierdzanie zostalo ukonczone. SQL> select status 2 from v$result_cache_objects 3 where name like '%F_GET_STATUS%' 4 and TYPE='Result' 5 / STATUS --------- Invalid

Jak widać w powyższym przykładzie, zaraz po odwołaniu się do funkcji otrzymaliśmy opublikowany wynik w naszym buforze, z którego będzie korzystało każde następne wywołanie funkcji z takim samym parametrem wejściowym. Jednak po modyfikacji tabeli, na której oparta była funkcja (wskazane przez relies_on), nasz zbuforowany wynik uległ inwalidacji dzięki temu mamy pewność otrzymywania wiarygodnych danych. Zupełnie inaczej ma się sprawa, gdy nie użyjemy klauzuli relies_on w takim przypadku możemy otrzymać nieprawdziwy wynik, ponieważ Oracle nie będzie miał informacji o zależności zbuforowanego wyniku funkcji od zawartości tabel, na których opierają się nasze wyliczenia. Wyrażenia regularne wyrażenia regularne stanowią bardzo potężne narzędzie w rękach programisty. Szczególnie istotne jest ich zastosowanie podczas wyrafinowanych opcji przeszukiwania ciągów znakowych lub walidacji danych. Obsługa wyrażań regularnych została dodana do bazy Oracle w wersji 10g. W wersji 11g została ona rozszerzona o nowe funkcjonalności do funkcji REGEXP_INSTR została dodana możliwość znalezienia N- tego sub wyrażenia. Znajdziemy też zupełnie nową funkcję REGEXP_COUNT, która oczywiście jak nie trudno się domyśleć, pozwala na zliczenie trafień na podstawie zadanego wzorca. Continue oraz simple_integer - jest to jedna z opcji, która została dodana do składni PL/SQL po wielu latach... Zdecydowana większość języków programowania posiada tę klauzulę, która pozawala na kontynuowanie pętli nadrzędnej przy spełnieniu określonych warunków. CREATE OR REPLACE PROCEDURE P_CONT_EXAMPLE AS v_sum simple_integer := 0; BEGIN <<BEFORE_LOOP>> for i in (select department_id, department_name from departments) loop v_sum := 0; for j in (select salary from employees where department_id=i.department_id) loop v_sum := v_sum + j.salary; if v_sum>19000 then dbms_output.put_line(i.department_name ' ' v_sum); continue BEFORE_LOOP; end if; end loop; end loop;

END P_CONT_EXAMPLE; Przy okazji trywialnego przykładu użycia klauzuli continue zdecydowałem się pokazać również nowy typ danych dodany do języka PL/SQL. Simple_integer jest pod typem, typu pls_integer ma dokładnie taki sam zakres jak pls_integer, różnica polega jednak na tym, że gdy dojdziemy do końca zakresu typu simple_integer nastąpi przekręcenie wartości zmiennej do najmniejszej wartości zakresu. Simple_integer jest również zadeklarowany jako not null, wymaga więc zainicjalizowania wartością, już na etapie deklaracji w naszym programie. Dynamiczny SQL Oracle ulepszył obsługę dynamicznego SQL zarówno za pomocą pakietu DBMS_SQL, jak również natywnego dynamicznego SQL (execute immediate). Oto kilka rozszerzeń dodanych do obsługi tej przydatnej funkcjonalności: Natywny dynamiczny SQL może przyjmować teraz 32kb tekstu. DBMS_SQL.PARSE zostało przeciążone dla używania CLOB. DBMS_SQL wspiera teraz abstrakcyjne typy danych, takie jak kolekcje. DBMS_SQL pozwala używać mechanizmu BULK BINDING używając typów zdefiniowanych przez użytkownika. Natywna kompilacja możliwość natywnej kompilacji procedur PL/SQL, była moim zdaniem zawsze jednym z największych plusów bazy Oracle. Możliwość przechowywania procedur w postaci bibliotek języka C dawała przecież zawsze nadzieję, na znacznie szybsze wykonanie kodu, zwłaszcza opartego na dużej liczbie obliczeń. Jednak wielokrotnie korzystanie z tego mechanizmu było ograniczone na wielu środowiskach. Wynikało to z faktu, że do tej pory skompilowany kod PL/SQL do postaci biblioteki języka C przechowywany był na serwerze, a co za tym szło wymagany był kompilator C dostępny dla właściciela bazy danych. Takie rozwiązanie z punktu widzenia bezpieczeństwa było niedopuszczalne na pewnych środowiskach. Tak więc funkcjonalność bardzo często pozostawała niewykorzystana. Oracle 11g ulepszył obsługę natywnej kompilacji PL/SQL począwszy od tej wersji bazy danych biblioteki C nie są przetrzymywane na serwerze lecz bezpośrednio w bazie danych, co likwiduje konieczność dostępu do kompilatora C. SQL> alter session set plsql_code_type=native; Sesja zostala zmieniona.

SQL> alter function f_get_status compile; Funkcja zostala zmieniona. SQL> select plsql_code_type 2 from DBA_PLSQL_OBJECT_SETTINGS 3 where name='f_get_status'; PLSQL_CODE_TYPE -------------------------------------------------------------------------------- NATIVE Jak widać na powyższym przykładzie, aby skompilować procedurę w trybie NATIVE, wystarczy ustawić jeden parametr sesji, oraz wykonać kompilację. Powyższa procedura, nie powoduje powstania żadnych plików na serwerze. Wszystko pozostaje wewnątrz bazy danych. Kosmetyka w PL/SQL zobaczymy również kilka poprawek kosmetycznych, które może nie wpływają jakoś znacznie na poprawę wydajności lub funkcjonalności systemu, ale na pewno są miłym ukłonem w stronę użytkownika. Tego typu poprawkami jest np. możliwość używania notacji mieszanej podczas wywoływania funkcji w wyrażeniu SQL, czy też opcja zastosowania przypisania wprost wartości sekwencji. SQL SQL jest językiem dostępu do danych, którego znajomość jest podstawą umiejętnością, zarówno dla dewelopera, jak i administratora. Oracle w najnowszej wersji swojej bazy danych dostarcza nam kilku ulepszeń, które zostaną opisane poniżej. Read-only tables komenda alter table dostarcza nam teraz możliwości uczynienia tabeli dostępną tylko do odczytu dla całej bazy danych (w tym również dla właściciela tabeli). Pojawiła się również nowa kolumna w tabeli słownika danych [DBA/ALL/USER]_TABLES, która określa stan tabeli READ_ONLY, której właściwymi wartościami są YES, lub NO. SQL> alter table employees read only; Tabela zostala zmieniona. SQL> select read_only 2 from user_tables 3 where table_name='employees'; REA --- YES

SQL> delete employees; delete employees * BLAD w linii 1: ORA-12081: operacja aktualizacji nie jest dozwolona dla tabeli "HR"."EMPLOYEES" Niewidzialne indeksy czy kiedykolwiek zdarzyło się Wam stworzyć indeks w celach testowych, tylko po to żeby okazało się, że niektóre plany wykonania zwariowały a wydajność wcale się nie poprawiła? A może usunęliście jakiś indeks, bo przeszkadzał podczas aktualizacji tabel a potem musieliście go odtwarzać, co trwało wiekami i przysparzało o nerwicę? W swej najnowszej wersji bazy danych, Oracle przedstawia nową funkcjonalność, która po zastosowaniu sprawia, że wskazany indeks staje się niewidoczny dla optymalizatora. SQL> select first_name, last_name, department_name 2 from employees e, departments d 3 where e.department_id=d.department_id; 106 wierszy zostalo wybranych. Plan wykonywania ---------------------------------------------------------- Plan hash value: 1343509718 -------------------------------------------------------------------------------------------- Id Operation Name -------------------------------------------------------------------------------------------- 0 SELECT STATEMENT 1 MERGE JOIN 2 TABLE ACCESS BY INDEX ROWID DEPARTMENTS 3 INDEX FULL SCAN DEPT_ID_PK * 4 SORT JOIN 5 TABLE ACCESS FULL SQL> alter index DEPT_ID_PK invisible; Indeks zostal zmieniony. SQL> select first_name, last_name, department_name 2 from employees e, departments d 3 where e.department_id=d.department_id; 106 wierszy zostalo wybranych. Plan wykonywania ---------------------------------------------------------- Plan hash value: 2052257371 ---------------------------------------------------------------------------------- Id Operation Name ---------------------------------------------------------------------------------- 0 SELECT STATEMENT * 1 HASH JOIN 2 TABLE ACCESS FULL DEPARTMENTS 3 TABLE ACCESS FULL EMPLOYEES

---------------------------------------------------------------------------------- Można nadpisać ustawienia niewidzialnych indeksów ustawiając parametr optimizer_use_invisible_indexes na wartość TRUE można skorzystać z ustawienia parametru na poziomie sesji, lub systemu co spowoduje, że pomimo włączenia niewidzialności, optymalizator będzie brał pod uwagę wszystkie indeksy. SQL Query Result Cache mechanizm ten jest przydatny, gdy mamy duże ilość danych, które przeważnie pozostają statyczne, a do których odwołujemy się często w zapytaniach (głównie funkcje agregujące). Dzięki tej funkcjonalności wyniki zapytań przechowywane są w obszarze współdzielonym (SHARED POOL), który począwszy od wersji 11g dzieli się na trzy główne obszary poza LIBRARY CACHE oraz DICTIONARY CACHE występuje RESULT CACHE, w którym właśnie przechowywane są zbuforowane wyniki naszych zapytań (w praktyce mamy więc kolejne miejsce, w którym mogą występować latche). Parametr result_cache_max_size może być ustawiony w celu manualnego określenia rozmiaru SQL Query Result Cache. Standardowo parametr ten ustawiany jest dynamicznie podczas startu instancji. Jeżeli parametr zostanie ustawiony na 0, wyłączona zostanie funkcjonalność buforowania wyników zapytań. (PL/SQL Function Result Cache omawiany wcześniej, również korzysta z tego obszaru). Rozważając wielkość bufora, Oracle będzie brał pod uwagę takie parametry jak memory_target (0,25% dla Result Cache), sga_target (0,50% dla Result Cache), shared_pool_size (1% dla Result Cache) Oracle nie powinien pozwolić na ustawienie parametru result_cache_max_size powyżej 75% shared pool. Kolejnymi istotnymi parametrami, które należy wziąć pod uwagę chcąc korzystać z omawianej funkcjonalności są: result_cache_mode oraz result_cache_max_result. Pierwszy z parametrów może przyjmować wartości MANUAL (ustawienie standardowe) aby skorzystać z buforowania, należy użyć w zapytaniu hinta, który wymusi takie działanie, lub FORCE Oracle będzie korzystał dla każdego zapytania z omawianego mechanizmu, jeżeli to tylko możliwe. Parametr ten może być modyfikowany zarówno na poziomie sesji jak i systemu. Drugi z wymienionych parametrów określa maksymalną procentową wielkość, jaką może zająć jeden zbuforowany wynik w result cache. Aby skorzystać z SQL Query Result Cache przy standardowych ustawieniach bazy danych

należy do zapytania dodać hint: result_cache. Kiedy parametr result_cache_mode ma ustawioną wartość FORCE, sytuacja wygląda dokładnie odwrotnie każdy SQL będzie korzystał z bufora i aby to uniemożliwić, należy zastosować hint: no_result_cache. Typowym rezultatem poprawnego działania mechanizmu jest zredukowanie liczby odczytów z bufora danych do zera. Należy jednak pamiętać, że w przypadku częstych operacji DML, omamiana funkcjonalność może doprowadzić do de optymalizacji, ponieważ będziemy mieli do czynienia z faktem częstych inwalidacji obiektów w result cache. SQL> select /*+ result_cache */ max(salary) 2 from employees; Plan wykonywania ---------------------------------------------------------- Plan hash value: 265868411 ---------------------------------------------------------------------------------------------------------- Id Operation Name ---------------------------------------------------------------------------------------------------------- 0 SELECT STATEMENT 1 RESULT CACHE f4cg36a3s8cm34yrg5nwtxug1h 2 SORT AGGREGATE 3 INDEX FULL SCAN (MIN/MAX) SALARY_IDX SQL> select name, status, row_count 2 from v$result_cache_objects 3 where cache_id='f4cg36a3s8cm34yrg5nwtxug1h'; NAME STATUS ROW_COUNT ------------------------------------------------------------ --------- ---------- select /*+ result_cache */ max(salary) Published 1 from employees Jak widać w powyższym przykładzie, na podstawie informacji dostarczonej przez plan wykonania zapytania, możemy odpytać perspektywę v$result_cache_objects (przedstawianą przy okazji omawiania PL/SQL Function Result Cache), aby sprawdzić statystyki dotyczące naszych zbuforowanych wartości. Ograniczenia SQL Query Result Cache są następujące: Brak obsługi zapytań do słownika danych. Brak obsługi zapytań do tabel tymczasowych Nie buforowane są wartości sekwencji Z bufora nie mogą korzystań niedeterministyczne funkcje Funkcjonalność nie obsługuje zapytań zwierających następujące funkcje

SQL: current_date, current_timestamp, userenv/sys_context, sys_guid, sysdate, sys_timestamp Client-Side SQL Query Result Cache buforowanie wyników zapytań w SGA, nie zredukuje ilości przepływu danych przez sieć. Jedną z tajemnic strojenia wydajności baz danych jest zdanie: Najszybszy dostęp do bazy danych to brak dostępu do bazy danych. Postępując zgodnie z tą zasadą powstały takie produkty, jak Oracle Coherence. Z myślą o tej zasadzie powstał też mechanizm, pozwalający na buforowanie wyników zapytań po stronie klienta. Jak na razie funkcjonalność dostępna jest wyłącznie dla sterowników opartych na OCI, takich jak: PHP, JDBC-OCI, OCCI, ODP.Net, Pro*C/C++, Pro*COBOL oraz ODBC. Performance Odkąd baza Oracle opiera swoją potęgę wydajnościową na optymalizatorze kosztowym, poprawne zbieranie i przechowywanie statystyk stało się jednym z głównych obszarów tematu strojenia bazy danych. Przyjrzyjmy się niektórym nowym cechom statystyk, które dostarcza nam baza Oracle 11g. Wiszą ce statystyki baza Oracle 11g daje nam opcję wyboru, czy zebrane statystyki zostaną opublikowane po zebraniu, czy otrzymają status wiszącej statystyki. Żeby określić, czy statystyki zostaną opublikowane bezpośrednio po zebraniu, czy też otrzymają status wiszących, możemy użyć funkcji GET_PREFS('PUBLISH') z pakietu DBMS_STATS. Jeżeli funkcja zwróci wartość TRUE, będzie to oznaczało, że statystyki zostaną opublikowane bezpośrednio po zebraniu. Aby zmienić ten parametr możemy skorzystać z funkcji SET_SCHEMA_PREFS (lub SET_TABLE_PREFS gdy chcemy wskazać konkretną tabelę), również znajdującej się w pakiecie DBMS_STATS. Gdy statystyki zostaną zebrane jako wiszące, możemy podejrzeć wygenerowane wartości w odpowiednich tabelach słownika danych: USER_TAB_PENDING_STATISTICS, USER_COL_PENDING_STATISTICS, USER_IND_PENDING_STATISTICS. Następnie w zależności od tego, czy uzyskamy zadowalający nas efekt, możemy statystyki opublikować (DBMS_STATS.PUBLISH_PENDING_STATS), bądź skasować (DBMS_STATS_DELETE_PEDING_STATS). SQL> select dbms_stats.get_prefs('publish','hr','employees2')

2 from dual; DBMS_STATS.GET_PREFS('PUBLISH','HR','EMPLOYEES2') -------------------------------------------------------------------------------- TRUE SQL> begin 2 dbms_stats.set_table_prefs('hr','employees2','publish','false'); 3 end; 4 / Procedura PL/SQL zostala zakonczona pomyslnie. SQL> delete employees2; 110 wierszy zostalo usunietych. SQL> commit; Zatwierdzanie zostalo ukonczone. SQL> begin 2 dbms_stats.gather_table_stats('hr','employees2'); 3 end; 4 / Procedura PL/SQL zostala zakonczona pomyslnie. SQL> select 'OPUBPLIKOWANE :' num_rows as pub 2 from user_tables 3 where table_name='employees2'; PUB ------------------------------------------------------- OPUBPLIKOWANE :110 SQL> select 'WISZACE :' num_rows as pend 2 from user_tab_pending_stats 3 where table_name='employees2'; PEND ------------------------------------------------- WISZACE :0 SQL> begin 2 dbms_stats.publish_pending_stats('hr','employees2'); 3 end; 4 / Procedura PL/SQL zostala zakonczona pomyslnie. SQL> select 'OPUBPLIKOWANE :' num_rows as pend 2 from user_tables 3 where table_name='employees2'; PEND ------------------------------------------------------- OPUBPLIKOWANE :0 Statystyki, które nie są opublikowane, nie mają wpływu na zmianę planu wykonania zapytania, wyjątkiem jest sytuacja, gdy wartość parametru optimizer_use_pending_statistics jest ustawiona na TRUE.

Statystyki wielokolumnowe i oparte na funkcjach Oracle 11g przedstawia nowe możliwości w generowaniu histogramów. Począwszy od tej wersji bazy danych mamy możliwość zbierania statystyk opartych na grupie kolumn oraz na funkcjach. Dzięki tej możliwości otwierają się zupełnie nowe możliwości wpływania na optymalizator kosztowy w celu wygenerowania najbardziej właściwego planu wykonania zapytania. Aby skorzystać z możliwości generowania statystyk wielokolumnowych należy uprzednio stworzyć grupę kolumn, do której będziemy się odwoływać. SQL> declare 2 v_name varchar2(30); 3 begin 4 v_name := dbms_stats.create_extended_stats(null,'employees','(department_id,job_id)'); 5 end; 6 / Procedura PL/SQL zostala zakonczona pomyslnie. SQL> begin 2 dbms_stats.gather_table_stats(null,'employees', method_opt=>'for all columns size auto for columns (DEPARTMENT_ID,JOB_ID)'); 3 end; 4 / Procedura PL/SQL zostala zakonczona pomyslnie. SQL> begin 2 dbms_stats.gather_table_stats(null,'employees', method_opt=>'for all columns size auto for columns (lower(first_name))'); 3 end; 4 / SQL> select extension_name, extension 2 from user_stat_extensions 3 where table_name='employees'; EXTENSION_NAME EXTENSION ------------------------------ ------------------------------------------------------------ SYS_STUCCK0PNI_XUVBAGRNRRUF29S ("DEPARTMENT_ID","JOB_ID") SYS_STUKTFUBS35V1$LRO53L2Z$F8R (LOWER("FIRST_NAME")) Jakkolwiek funkcjonalność wydaje się być ciekawa oraz obiecująca, przeprowadzone testy wskazują, że mechanizm jest jeszcze niestabilny a zachowanie optymalizatora trudne do przewidzenia. Bind-Aware Peeking do tej pory używanie zmiennych wiązanych mogło nieść ze sobą ryzyko zmniejszenia wydajności zapytań, gdy w kolumnach znajdowały się dane o nierównomiernym rozkładzie, nadające się do zakładania histogramów. Oracle 11g proponuje nam rozwiązanie mające uwolnić nas od problemu wybierania, kiedy używać

zmiennych wiązanych a kiedy jednak lepiej jest użyć literałów. Dzięki nowemu mechanizmowi Bind-Aware Peeking, SQL przy pierwszym wykonaniu przejdzie normalne, twarde parsowanie. Następne wykonanie spowoduje znalezienie zbuforowanego planu wykonania zapytania, unikając twardego parsowania. Po wykonaniu SQL, jego statystyki dotyczące wykonania zostaną porównane ze statystykami z poprzednich wykonań. Jeżeli Oracle zauważy, że porównanie wypada na niekorzyść, oznaczy nasz kursor jako bind-aware. Dzięki temu przy kolejnych wykonaniach będzie sprawdzana selektywność predykatów i, jeśli trzeba, wygenerowany nowy plan wykonania zapytania. Efektem takiego działania jest powstanie kilku różnych planów wykonania zapytania dla tego samego kursora, zawierającego zmienne wiązane. Odpowiedni plan będzie wybierany na podstawie wartości przypisanych do zmiennych wiązanych.