Evaluarea interogărilor la serverul Oracle

Gestiunea datelor memorate în bazele de date se realizează numai prin instrucţiuni SQL. Performanţa aplicaţiilor depinde foarte mult de viteza cu care serverul de date execută aceste instrucţiuni.
Atunci când o instrucţiune SQL este trimisă serverului ORACLE pentru execuţie, se generează un Plan de Execuţie. Acest plan se generează prin parcurgerea mai multor paşi, dintre care amintim:

  1. Analiza sintactică - se verifică dacă sintaxa instrucţiunii SQL este corectă
  2. Analiza semantică - se verifică dacă obiectele (componentele) referite în instructiune există şi sunt accesibile (deci dacă utilizatorul curent are drepturi de utilizare a componentelor din instrucţiune)
  3. Inlocuirea view-urilor- dacă instrucţiunea SQL conţine referiri la view-uri, ele se înlocuiesc cu definiţia lor (cu instrucţiuni Select-sql)
  4. Transformarea instrucţiunii într-o expresie cu operatori din algebra relaţională
  5. Transformarea expresiei relaţionale într-o formă optimală prin folosirea unor rezultate din algebra relaţională. Cu astfel de transformări o expresie relaţională este convertită în altă expresie relaţională echivalentă, dar care are un cost general mai mic pentru evaluare.
  6. Optimizarea ultimei expresii relaţionale obţinute. Viteza de execuţie este influenţată de mulţi factori, dintre care se pot aminti: numărul şi structura indecşilor asociaţi tabelelor, structura join-urilor, condiţiile de filtrare din clauza WHERE, numărul de înregistrări, dimensiunea înregistrărilor, etc.
    Serverele de baze de date oferă modalităţi de optimizare şi de urmărire a operaţiilor implicate în execuţia instrucţiunilor SQL.
  7. Generarea unui plan de execuţie
  8. Evaluarea planului astfel determinat

Serverul Oracle analizează fiecare instrucţiune SQL şi alege cel mai bun plan de execuţie, din punctul de vedere al timpului de răspuns şi al resurselor necesare execuţiei instrucţiunii.

La alegerea tipului de optimizare se au în vedere mai mulţi parametri, dintre care amintim:

Alegerea tipului de optimizare

Alegerea tipului de optimizare se poate face în unul din următoarele moduri:

  1. La nivelul instanţei (global pentru toate sesiunile de lucru) prin parametrul de iniţializare OPTIMIZER_MODE. Acest parametru poate lua următoarele valori:
  2. La nivelul sesiunii printr-o instructiune ALTER SESSION, care precizează valoarea parametrului OPTIMIZER_MODE amintit mai sus:
    ALTER SESSION SET OPTIMIZER_MODE=
           {ALL_ROWS | 
    	   FIRST_ROWS_1 | FIRST_ROWS_10 | FIRST_ROWS_100 | FIRST_ROWS_1000 | 
    	   FIRST_ROWS |CHOOSE | RULE}
    

  3. La nivelul instrucţiunilor SQL prin folosirea unor directive, numite şi hinturi, precizate efectiv în instrucţiune. Aceste directive reprezintă sugestii pentru optimizare şi apar în instructiunea SQL. Ele schimbă configuraţia de optimizare stabilită prin fişierul de iniţializare (parametrul OPTIMIZER_MODE) sau prin instrucţiunea ALTER SESSION.
    Exemplu:
    SELECT /*+ALL_ROWS*/ lista_coloane FROM ...
Valoarea curentă a parametrilor sistemului (inclusiv tipul de optimizare curent) se pot afla prin instrucţiunea:
select * from V$PARAMETER order by name;

Optimizare bazată de reguli

Acest tip de optimizare foloseşte o mulţime de reguli fixe, care precizează ordinea optimă de execuţie a operatorilor relaţionali şi care nu sunt generate de contextul din baza de date (de dimensiunea tabelelor, de existenţa şi tipul indecşilor, etc.). La fiecare regulă se asociază un rang care îi determină gradul de prioritate atunci când se construieşte planul de execuţie. Amintim câteva dintre aceste reguli.
RangulMetoda de acces la interogări
1Acces la o singură înregistrare prin ROWID
2Acces la o singură înregistrare (cu cheie unică sau primară) printr-un join cluster
3Acces la o singură înregistrare prin cheia unui hash cluster, cheie care este primară sau unică
4Acces la o singură înregistrare printr-o cheie primară sau unică
5Cluster Join cu o cheie din acelaşi cluster
6Acces la înregistrări prin cheia cluster-ului hash
7Acces la înregistrări prin cheia cluster-ului index
8Acces la înregistrări printr-un index compus - conţinând mai multe coloane
9Acces la înregistrări printr-un index după o singură coloană
10Căutări (condiţii filtru) cu legătură între ele după o coloană indexată (de ex.>= AND <=)
11Căutări (condiţii filtru) fără legătură între ele după coloane indexate
12Sort-merge join
13Funcţii MIN sau MAX după o coloană indexată
14Clauza ORDER BY după o coloană indexată
15Scanare completă a tabelei
Observaţie. Acest tip de optimizare nu mai este dezvoltat de Oracle.

Optimizare bazată pe cost

Acest tip de optimizare foloseşte anumite informaţii statistice din dicţionarul de date. Astfel de informaţii statistice despre tabelele existente în baza de date, sau despre coloanele acestor tabele, clusteri şi indecşi, sunt memorate în dicţionarul de date şi sunt create (sau reactualizate) prin comenzi ANALYZE sau cu facilităţile pachetului DBMS_STATS. Dacă nu există informaţii statistice despre o sursă de date, atunci se foloseşte optimizatorul bazat pe reguli.
Se pot folosi în paralel cele două tipuri de optimizatoare dacă unele tabele sunt analizate şi altele nu. Dacă cel puţin unul din tabelele implicate în instrucţiunea SQL este analizată, atunci folosirea optimizării bazate pe cost (mai avantajoasă) devine posibilă.
Modul de analiză a tabelelor şi tipul informaţiilor calculate este importantă pentru determinarea performanţei instrucţiunilor SQL. Tot la fel de important este şi momentul în care se face analiza şi cât de des se determină aceste informaţii statistice.
Există două variante de a analiza înregistrările dintr-un tabel:

Dacă se foloseşte optimizatorul bazat pe cost, atunci informaţiile statistice din dicţionarul de date (despre tabele, indexuri, clustere) trebuie calculate periodic, mai ales după multe operaţii de modificare sau dacă distribuţia valorilor din coloane are schimbări semnificative în timp. Pentru eficienţa operaţiilor se poate scrie un script (o procedură) care să conţină comenzi ANALYZE pentru tabele utile dintr-o schemă dată. Acest script (procedură) trebuie executat periodic (manual sau prin folosirea pachetului DBMS_JOB).

Exemple de utilizare:

ANALYZE TABLE tabel COMPUTE STATISTICS;

se evaluează întregul tabel.

ANALYZE TABLE tabel ESTIMATE STATISTICS;

se evaluează primele 1064 de înregistrări.

ANALYZE TABLE tabel ESTIMATE STATISTICS SAMPLE 10 PERCENT;

se evaluează primele 10% înregistrări.

ANALYZE TABLE tabel ESTIMATE STATISTICS SAMPLE 1000 ROWS;

se evaluează primele 1000 de înregistrări.

O altă modalitate de determinarea a informaţiilor statistice constă în folosirea pachetului dbms_stats.

Pe scurt, analiza bazată pe costuri are următorii paşi:

Dacă un tabel a fost analizat şi nu mai sunt necesare statisticile, acestea se pot şterge folosind:

ANALYZE TABLE tabel DELETE STATISTICS;

Cu ajutorul view-ului dba_tables se pot obţine informaţii cu privire la statisticile existente.

Exemplu pentru obţinerea tabelelor dintr-o schemă pentru care există statistici colectate (coloana sample_size precizează numărul de înregistrări folosite la calculul informaţiilor statistice):

select last_analyzed, table_name, num_rows, sample_size 
from dba_tables where owner='STUD1' order by last_analyzed;

Observaţie. Analiza tabelelor, pentru informaţii statistice, este o operaţie costisitoare (ca timp) dacă dimensiunea tabelelor este mare.

Folosire index la generarea interogărilor

Din punct de vedere logic un index este o listă de perechi: o valoare a expresiei pentru care s-a creat indexul, adresele înregistrărilor care au această valoare pentru expresia de cheie.
Un index se crează:

La consultarea unui tabel serverul de date are două variante:

Indecşii cresc performantele instrucţiunilor SELECT, UPDATE, DELETE, deoarece se determină mai repede înregistrările folosite de aceste instrucţiuni, dar scad performanţa instrucţiunii INSERT.

Tipuri de indexuri

  1. Indecşi pentru o singură coloană, memoraţi ca un B-arbore.
  2. Indecşi pentru o concatenare de coloane, memoraţi ca un B-arbore.
  3. Indecşi pentru valorile unei expresii (începând cu versiunea Oracle 8i). Se recomandă numai dacă în clauzele where se va folosi această expresie.

    Exemplu:

    create index studenti1 on studenti(substr(cnp,2,2));

  4. Indecşi de tip bitmap: conţin pentru fiecare valoare (a coloanei, a colectiei de coloane, a expresiei pentru care se construieşte indexul) câte un vector de valori 1 şi 0, câte o poziţie în acest vector pentru fiecare înregistrare din tabel. O valoare binară din acest vector precizează dacă înregistrarea conţine valoarea respectivă sau nu. Este recomandat pentru coloane cu puţine valori distincte (deci există multe repetări ale valorilor), altfel dimensiunea indexului poate fi foarte mare.

    Exemplu:

    create bitmap index studenti2 on studenti(substr(cnp,6,2));

    Aceşti indecşi sunt eficienţi în interogările ce folosesc operatorul de egalitate "=" sau "IN".

  5. Index pentru date xml
  6. Alte tipuri de index: cluster, hash

Observaţie. Periodic este necesară re-crearea indexurilor. O cale rapidă constă în folosirea instructiunii ALTER INDEX cu optiunea REBUILD.

Exemplu:

alter index studenti1 REBUILD;