CATEGORII DOCUMENTE |
Un index este o structura optionala a bazei de date care permite accesarea directa a unui rand dintr-un tabel. Indecsii pot fi creati pentru una sau mai multe coloane a unui tabel, in acest ultim caz folosindu-se denumirea de indecsi compusi sau indecsi concatenati. Un index este utilizat de catre baza de date pentru a gasi rapid valori pentru coloana sau coloanele pentru care a fost creat indexul, in acest mod furnizand o cale de acces directa la liniile asociate acestora fara a mai fi necesara investigarea fiecarui rand din tabel. Practic, in momentul in care se doreste cautarea anumitor inregistrari ale caror valori indeplinesc un anumit criteriu, in loc sa se parcurga tabelul, se parcurge indexul, acesta din urma furnizand localizarea exacta a inregistrarilor ce indeplinesc criteriul de cautare prin precizarea ROWID. Asa cum am mai precizat in sectiunea 4.5, identificatorul de rand ROWID reprezinta in primul rand cel mai rapid mod de a localiza o anumita inregistrare. Prin urmare pentru a gasi o anumita inregistrare in modul cel mai rapid se determina ROWID-ul acesteia in loc sa se parcurga secvential tabelul respectiv. Fara indecsi, operatii precum determinarea unicitatii sau ordonarea valorilor unei coloane ar putea consuma multe resurse si timp.
Prezenta indecsilor este transparenta pentru utilizator si aplicatie, ei neputand fi referiti in mod direct prin interogari. In plus, sintaxa unei comenzi SQL nu este in nici un fel influentata de existenta indecsilor, iar rezultatele oricarei interogari vor fi aceleasi indiferent daca exista indecsi sau nu. Pe de alta parte insa, utilizarea corecta a acestora poate influenta in cel mai mare grad eficienta unei interogari: diferenta va consta in rapiditatea cu care se executa comanda si nu in rezultatele acesteia. Foarte multe sisteme ce raporteaza probleme de performanta sufera din cauza lipsei unui index sau din cauza absentei unui index optim. Informatia continuta in indecsi este redundanta, ea fiind derivata din informatia care exista in tabele.
Indecsii sunt independenti din punct de vedere fizic si logic de datele din tabelul de baza. Un index poate fi creat si distrus fara ca datele din tabelul de baza sau ceilalti indecsi sa aiba de suferit. Singurul lucru pe care indexul il va modifica va fi durata accesului la datele tabelului, acesta devenind mai lent in absenta indexului. Evident, odata cu stergerea unui tabel sunt stersi si indecsii asociati acestuia.
Indecsii pot sa fie unici sau ne-unici. Indecsii unici garanteaza faptul ca nu va exista nici o pereche de linii care sa aiba valori identice pentru coloana sau grupul de coloane pentru care a fost definit indexul. Valorile Null nu sunt considerate pentru unicitate. Un rand cu valoarea Null in coloana indexata nu va fi inregistrat in index, deci un index unic nu va impiedica stocarea mai multor randuri cu o valoare Null in coloana indexata. Un index ne-unic nu impune nici o restrictie in legatura cu valorile din coloanele care il definesc.
Odata definit, un index este actualizat de catre baza de date ori de cate ori au loc modificari ale datelor tabelului. Aceasta inseamna, ca ori de cate ori au loc inserari, stergeri sau modificari ale datelor unui tabel, toti indecsii acelui tabel trebuie actualizati in mod automat, acest lucru avand ca efect incetinirea acestor operatii asupra datelor tabelului. Cu alte cuvinte, existenta indecsilor sporeste viteza accesului la datele tabelului pe de o parte, dar in acelasi timp incetineste operatiile de modificare ale acestora. De aceea, nu trebuie creat un index pentru fiecare coloana a unui tabel (desi acest lucru este posibil), ci pentru anumite coloane cheie ale acestuia. De exemplu, se recomanda indexarea coloanelor care contin in majoritate valori unice sau un domeniu larg de valori sau coloane dupa care se fac dese cautari sau ordonari. Deoarece prezenta indecsilor poate avea un impact semnificativ asupra eficientei aplicatiei in continuare prezentam cateva sugestii privind folosirea acestora:
Ce tabele trebuie indexate:
Indexati tabelele pentru care majoritatea interogarilor selecteaza doar un numar redus de randuri (sub 5%). Interogarile care selecteaza un numar mare de randuri nu folosesc in mod eficient indecsii.
Nu indexati tabele ce contin putine inregistrari deoarece in acest caz accesul secvential va fi mai rapid.
Indexati tabelele care sunt interogate folosind clauze SQL simple. Clauzele SQL mai complexe nu folosesc cu aceeasi eficienta indecsii.
Nu indexati tabelele care sunt actualizate frecvent. Inserarile, modificarile si stergerile sunt ingreunate de existenta indecsilor. Decizia de a indexa un tabel trebuie luata pe baza raportului dintre numarul de interogari si cel de actualizari efectuat asupra acestuia.
Indexati tabelele care nu au valori duplicate in coloanele care apar in clauza WHERE a celor mai frecvente interogari.
Ce coloane trebuie indexate:
Folositi coloanele cele mai frecvent folosite in clauza WHERE a interogarilor.
Nu indexati coloane care nu au multe valori unice. Totusi, incepand cu versiunea Oracle8 se pot indexa coloane care nu au multe valori distincte cu ajutorul indexului de tip bitmap asupra caruia vom reveni in cuprinsul acestui capitol.
Coloanele care au valori unice sunt candidate foarte bune pentru indexare. De altfel, Oracle creeaza in mod automat indecsi unici pentru coloanele definite ca primary key sau unique. In plus, din punct de vedere logic, este preferabil ca indecsii unici sa nu fie definiti in mod explicit, ci prin intermediul constrangerilor primary key si unique - acesta deoarece unicitatea este un concept logic si ar trebui sa fie asociat cu definitia tabelului.
Coloanele care sunt folosite pentru a face legatura dintre tabele sunt in general candidate pentru indexare. In general, se recomanda indexarea cheilor straine.
In anumite situatii, folosirea indecsilor compusi poate fi mai eficienta decat a celor individuali. De exemplu, crearea indecsilor compusi este recomandabila cand doua coloane nu sunt unice fiecare in parte dar combinatia lor este unica sau are in majoritate valori unice. De asemenea, se recomanda crearea indecsilor compusi atunci cand interogarile uzuale ale tabelului contin in clauza where mai multe coloane individuale legate prin AND
Indecsii consuma spatiu in baza de date la fel ca si tabelele si exista intr-un spatiu tabel la fel ca si acestea. Spatiul necesar indecsilor pentru tabele mari este de obicei semnificativ, asa ca trebuie planificat din momentul in care se proiecteaza baza de date.
1 Crearea, modificarea si distrugerea indecsilor
In SQL un index se creeaza folosind comanda create index. O sintaxa simplificata a acestei comenzi este prezentata in continuare:
CREATE UNIQUE INDEX nume_index
ON tabel (coloana [,coloana] )
PCTFREE intreg] [PCTUSED intreg]
TABLESPACE spatiu_tabel]
STORAGE parametrii_de_stocare]
unde:
Daca este specificata optiunea unique, indexul creat este unic, altfel nu.
Valorile parametrilor PCTFREE si PCTUSED determina gradul de utilizare a blocurilor din extinderile segmentului de index, vezi sectiunea 4.4.
TABLESPACE specifica spatiul tabel in care va fi stocat indexul. Daca acesta nu este mentionat explicit, se va folosi spatiul tabel implicit (default) al utilizatorului care este proprietarul schemei din care face parte indexul. In general, se recomanda stocarea indexului intr-un spatiu tabel diferit de cel in care este stocat tabelul sau; in acest caz Oracle poate accesa tabelul si indexul in paralel, obtinandu-se astfel o crestere a performantelor interogarilor.
Clauza STORAGE este folosita pentru setarea parametrilor de stocare (INITIAL NEXT PCTINCREASE MINEXTENTS MAXEXTENTS) prin intermediul carora se specifica marimea si modul de alocare a extinderilor segmentului de index, vezi sectiunea 4.1.1.
Urmatoarele comenzi SQL creeaza un index compus sal_dept_ind pentru coloanele cod_dept si cod_tara din tabelul salariat si respectiv un index unic pentru coloana nume_dept a tabelului departament
CREATE INDEX sal_dept_ind ON salariat(cod_dept, cod_tara);
CREATE UNIQUE INDEX nume_dept_ind ON departament(nume_dept);
Crearea indecsilor unui tabel se recomanda a se face dupa ce tabelul a fost populat cu date - aceasta deoarece existenta indecsilor incetineste in mod evident inserarea datelor.
La definirea constrangerilor primary key sau unique sau la activarea acestora, Oracle creeaza in mod automat indecsi unici pentru coloanele sau grupurile de coloane respective. In acest caz numele indexului coincide cu numele constrangerii.
La fel ca si in cazul tabelelor, parametrii de stocare a indecsilor pot fi modificati ulterior. Pentru aceasta se foloseste comanda ALTER INDEX cu urmatoarea sintaxa:
ALTER INDEX nume_index
STORAGE parametrii_de_stocare
De exemplu:
ALTER INDEX sal_dept_ind
STORAGE (NEXT 400K MAXEXTENTS 100);
De asemenea, Oracle8 permite alocarea si dealocarea manuala a spatiului utilizat de un index.
Alocarea manuala a spatiului pentru un index inseamna adaugarea manuala a unei noi extinderi. De exemplu, alocarea manuala se poate face inaintea unei perioade in care se va inregistra o activitate intensa de inserari in tabela pe care este bazat indexul. In acest caz, alocarea manuala previne extinderea dinamica a indexului (alocarea dinamica a unei noi extinderi), impiedicand astfel cresterea timpului de executie. Dealocarea spatiului asociat unui index reprezinta eliberarea spatiului nefolosit de acesta.
Pentru a aloca sau dealoca spatiul utilizat de un index se foloseste comanda ALTER TABLE cu urmatoarele sintaxe:
ALTER INDEX nume_index
ALLOCATE EXTENT SIZE intreg [K M
[DATAFILE specificatie_fisier_de_date] )
respectiv
ALTER INDEX nume_index
DEALLOCATE UNUSED KEEP intreg [K M
Semnificatia parametrilor din aceste comenzi este aceeasi ca si in cazul tabelelor, vezi sectiunea 6.1.5.
Un index poate fi distrus folosind comanda SQL DROP INDEX cu urmatoarea sintaxa:
DROP INDEX nume_index
De exemplu:
DROP INDEX sal_dept_ind;
Un index nu poate fi sters daca el a fost creat in mod automat, ca parte a definirii sau a activarii unei restrictii PRIMARY KEY sau UNIQUE. In acest caz indexul este sters automat la stergerea sau dezactivarea constrangerii.
Stergerea unui index se face de obicei daca indexul nu mai este necesar, daca se doreste reconstruirea sa (despre care vom discuta in continuare) sau inainte de incarcarea masiva a datelor intr-un tabel; stergerea unui index inainte de incarcarea masiva a datelor si recrearea lui dupa terminarea incarcarii va duce la imbunatatirea performantei incarcarii precum si la utilizarea spatiului alocat indexului in mod mai eficient.
Pentru a reconstrui un index se pot folosi doua metode. Prima este de a sterge indexul folosind comanda DROP INDEX si de a il recrea folosind comanda CREATE INDEX. A doua este folosirea ALTER INDEX cu optiunea REBUILD folosind sintaxa:
ALTER INDEX nume_index REBUILD
PCTFREE intreg] [PCTUSED intreg]
TABLESPACE spatiu_tabel]
STORAGE parametrii_de_stocare]
REVERSE|NOREVERSE
Reconstruirea unui index se face in urmatoarele situatii:
indexul existent trebuie mutat intr-un spatiu tabel diferit (de exemplu, daca indexul a fost creat in mod automat de o constrangere de integritate, caz in care el se gaseste in acelasi spatiu tabel cu tabelul).
un index normal trebuie convertit intr-un index cu cheie inversa (despre tipurile de indecsi vom vorbi in continuare). Pentru a converti un index obisnuit intr-un index cu cheie inversa se foloseste comanda ALTER INDEX . REBUILD cu optiunea REVERSE (optiunea contrara este NOREVERSE, care este si optiunea implicita)
pentru a recupera spatiul de stocare sau pentru a schimba atributele fizice de stocare.
In cazul reconstruirii indexului folosind comanda ALTER INDEX . REBUILD, in timpul crearii noului index este pastrat si indexul original, astfel ca indexul poate fi folosit de interogari si in timpul acestei operatii. Principalele avantaje ale fiecarei dintre cele doua metode sunt rezumate in tabelul de mai jos:
Sterge si recreeaza |
Foloseste optiunea REBUILD |
Poate redenumi indexul. |
Nu poate redenumi indexul. |
Poate schimba intre UNIQUE si non-UNIQUE. |
Nu poate schimba intre UNIQUE si non-UNIQUE |
Poate schimba intre tipul de index bazat de arbore B* si indexul de tip bitmap (vezi paragrafele urmatoare) |
Nu poate schimba intre tipul de index bazat de arbore B* si indexul de tip bitmap. |
Are nevoie de spatiu doar pentru o copie a indexului. |
Are nevoie de spatiu suplimentar pentru a duplica indexul in mod temporar. |
Necesita sortare. |
Nu necesita sortare, folosindu-se indexul initial. |
Index este indisponibil in perioada dintre stergere si recreare. |
Indexul este disponibil interogarilor. |
Nu se poate folosi aceasta metoda daca indexul a fost creat de o constrangere PRIMARY KEY sau UNIQUE. In acest caz stergerea indexului se poate face prin stergerea sau dezactivarea constrangerii respective. |
Se poate folosi aceasta metoda daca indexul a fost creat de o constrangere PRIMARY KEY sau UNIQUE. |
2 Tipuri de indecsi
Index de tip arbore B*
Cel mai intalnit tip de index folosit de Oracle este indexul de tip arbore B* (B*-tree index sau balanced tree index). Acesta este tipul de index creat la executarea unei comenzi standard CREATE INDEX si tipul de index la care ne-am referit in sectiunea de mai sus. Un arbore B*, este un arbore in care pentru gasirea oricarei valori din arbore sunt necesari acelasi numar de pasi, indiferent de valoarea cautata. Figura 6.5 ilustreaza structura unui index de tip arbore B*.
Algoritmul de cautare intr-un astfel de arbore compara valoarea ceruta cu valorile din nivelul superior de blocuri; in functie de aceasta comparatie, valoarea cautata este apoi comparata cu unul din blocurile inferioare si comparatia continua pana cand se ajunge la ultimul nivel de blocuri, numite blocuri frunza. Blocurile frunza ale indexului contin toate valorile datelor indexate si valoarea ROWID a randului asociat pentru fiecare dintre aceste valori. Un arbore B* este intotdeauna balansat, adica distanta de la varf la oricare nod frunza este aceeasi pentru toate nodurile. Cu cat este mai mare aceasta distanta, cu atat este mai mare numarul de blocuri ce trebuie examinate pentru a ajunge la un bloc frunza si, prin urmare cu atat mai lent este indexul. Pentru un index unic, exista un singur ROWID pentru fiecare valoare. Cand un bloc frunza se umple, atunci este creat un bloc nou. Unele informatii din blocul plin sunt mutate in noul bloc, acesta din urma devenind bloc frunza. Deoarece un arbore B* este un arbore balansat, activitatile intr-un index nu se termina aici, ducand uneori pana la schimbarea informatiilor din nodul radacina al arborelui sau chiar pana la inlocuirea nodului radacina cu un altul. Teoria indecsilor de tip arbore B* este dincolo de scopul acestei carti, pentru mai multe informatii se poate consulta [3] [Basca97] sau literatura de specialitate care se ocupa cu structuri de date.
Figura 6.5 : structura interna a unui index de tip arbore B*.
Pentru indecsi neunici, daca exista mai multe ROWID pentru aceeasi valoare a datelor indexate, atunci si acestea sunt sortate, deci indecsii neunici sunt sortati intai dupa valoarea datelor si apoi dupa ROWID. Valorile nule nu sunt indexate, cu exceptia indecsilor de cluster, vezi mai jos.
Index partitionat
O noutate adusa de versiunea Oracle8 este posibilitatea de partitionare a unui index. Asa cum un tabel poate fi partitionat, la randul lui un index de tip arbore B* poate fi si el partitionat. Indecsii partitionati sunt folositi in cazul tabelelor mari pentru a stoca valorile coloanei indexate in mai multe segmente. Practic, pentru fiecare partitie a tabelului poate fi creata o partitie a unui index. Prin urmare, partitionarea permite stocarea unui index in mai multe spatii tabel. Unul din avantajele partitionarii este descresterea domeniului de valori in care indexul cauta o anumita valoare.
Pentru a crea un index partitionat se foloseste comanda CREATE index cu clauza PARTITION. Un index partitionat, la fel ca si un tabel partitionat (vezi sectiunea 6.1.2) permite definirea unor spatii table si parametrii de stocare diferiti pentru fiecare parte. Exista doua moduri de a defini un index partitionat: local si global.
local: partitiile indexului sunt similare cu partitiile tabelului; in acest caz indexul este partitionat in functie de aceeasi coloana, pe acelasi interval de valori ca si tabelul la care se refera; partitiile trebuiesc enuntate in aceeasi ordine ca si partitiile tabelului la care se refera. Aceasta este metoda cel mai des folosita deoarece partitionarea este dirijata de tabelul de baza. Sintaxa pentru crearea unui index partitionat local este urmatoarea:
CREATE INDEX nume_index
ON tabel (coloana [,coloana] )
LOCAL
(PARTITION nume_partitie
[PCTFREE intreg] [PCTUSED intreg]
[TABLESPACE spatiu_tabel]
[STORAGE parametrii_de_stocare]
PARTITION nume_partitie VALUES LESS GREATER THAN (lista_valori)
[PCTFREE intreg] [PCTUSED intreg]
[TABLESPACE spatiu_tabel]
[STORAGE parametrii_de_stocare]].)
Urmatorul exemplu creeaza un index partitionat local pe baza tabelului partitionat salariat_part din sectiunea 6.1.2.
CREATE INDEX nume_sal_part_ind ON salariat_part(nume)
LOCAL
(PARTITION salariu_mic
tablespace ts_ind_alfa
storage (initial 10K next 10K),
PARTITION salariu_mediu
tablespace ts_ind_beta
storage (initial 20K next 20K),
PARTITION salariu_mare
tablespace ts_ind_alfa
storage (initial 10K next 10K));
global: partitiile indexului sunt definite de utilizator si nu sunt similare cu partitiile tabelului la care se refera indexul. Sintaxa pentru crearea unui index partitionat global este urmatoarea:
CREATE INDEX nume_index
ON tabel (coloana [,coloana] )
PARTITION BY RANGE (lista_coloane)
(PARTITION nume_partitie VALUES LESS GREATER THAN (lista_valori)
[PCTFREE intreg] [PCTUSED intreg]
[TABLESPACE spatiu_tabel]
[STORAGE parametrii_de_stocare]
PARTITION nume_partitie VALUES LESS GREATER THAN (lista_valori)
[PCTFREE intreg] [PCTUSED intreg]
[TABLESPACE spatiu_tabel]
[STORAGE parametrii_de_stocare]].)
Urmatoarea comanda creeaza indexul global nume_sal_ind pentru tabela salariat, index ce va avea doua partitii:
CREATE INDEX nume_sal_ind ON salariat(nume) GLOBAL PARTITION BY RANGE (nume)
(PARTITION VALUES LESS THAN ('N')
TABLESPACE ts_alfa_ind,
PARTITION VALUES LESS THAN (MAXVALUE)
TABLESPACE ts_beta_ind);
Index de cluster
Un index de cluster (index de grup) este un index bazat pe coloanele comune ale unui cluster. Nu se pot efectua nici un fel de comenzi DML asupra unui cluster pana cand nu a fost creat un index de cluster. Clusterele si indecsii de cluster sunt prezentati pe larg in sectiunea 6.4. Gruparea tabelelor in cluster nu afecteaza crearea de indecsi suplimentari pentru tabele individuale; acestia pot fi creati sau distrusi ca de obicei.
Index cu cheie inversa
Un index cu cheie inversa (reverse-key index) reprezinta o noua metoda (adusa de versiunea Oracle8) de a imbunatati anumite tipuri de cautari. Asa cum s-a discutat pana acum, pentru sporirea eficientei cautarilor unor valori in baza de date se folosesc de obicei arborii B*. Exista totusi unele cazuri in care acestia ingreuneaza accesul la date. De exemplu, presupunem ca avem o coloana indexata ce contine prenumele a mii de persoane. Sa presupunem de asemenea ca in aceasta coloana exista mii de prenume ce incep cu litera 'S'. In momentul in care se doreste inserarea mai multor inregistrari ce incep cu litera 'S' pot aparea strangulari ale operatiilor de citire/scriere deoarece modificarile in index-ul asociat coloanei vor aparea in acelasi nod al arborelui. Indecsii cu cheie inversa sunt folositi tocmai in aceasta situatie deoarece ei stocheaza datele in mod invers. Prin urmare, prenumele 'SANDU' va fi stocat tot intr-un arbore B* ca 'UDNAS'. Acest tip de index este folositor numai in cazul cautarii in arbore a unor valori exacte.
Un index cu cheie inversa se creeaza folosind comanda CREATE INDEX cu optiunea REVERSE, de exemplu:
CREATE INDEX sal_prenume_ind ON salariat(prenume) REVERSE;
Un index obisnuit se poate tranforma in index cu cheie inversa folosind comanda ALTER INDEX . REBULD cu optiunea REVERSE. De exemplu:
ALTER INDEX sal_prenume_ind REBUILD REVERSE;
Index de tip bitmap
Un alt tip de index, introdus in Oracle8, este indexul de tip bitmap. Intr-un astfel de index, in loc de a se stoca valorile propriu-zise ale coloanei indexate, indexul stocheaza un bitmap format pe baza acestor valori. Cu alte cuvinte, indexul tine un bitmap pentru fiecare rand, bitmap care contine un bit pentru fiecare rand din tabel. Bitul este 1 daca valoarea respectiva este continuta in acel rand si 0 daca nu este. De exemplu, sa presupunem ca avem un index de tip bitmap creat pe baza coloanei culoare dintr-un tabel masina, vezi figura 6.6.
Tabel masina
Nr_masina |
Marca |
Culoare |
Ford Mondeo |
Alb |
|
Dacia Nova |
negru |
|
Daewoo Cielo |
alb |
|
Daewoo Tico |
verde |
|
Ford Mondeo |
rosu |
|
Ford Mondeo |
albastru |
|
Dacia Nova |
alb |
|
Dacia Nova |
negru |
|
Daewoo Cielo |
verde |
|
Ford Mondeo |
verde |
|
Dacia Nova |
verde |
|
Daewoo Tico |
verde |
|
Ford Mondeo |
albastru |
|
Dacia Nova |
verde |
|
Daewoo Tico |
albastru |
|
Dacia Nova |
verde |
|
Ford Mondeo |
alb |
|
Daewoo Tico |
negru |
|
Dacia Nova |
verde |
|
Ford Mondeo |
verde |
Index de tip bitmap pentru coloana culoare
Culoare = alb |
Culoare = negru |
Culoare = verde |
Culoare = albastru |
Culoare = rosu |
| ||||
Figura 6.6
In acest exemplu, coloana culoare poate avea numai cinci valori: alb, negru, rosu, verde, albastru, iar in tabel sunt 20 de randuri. Bitmap-ul corespunzator fiecarei culori va avea 20 de biti, fiecare dintre acestia avand valoarea 1 cand masina va avea culoarea respectiva si 0 in caz contrar. Deci bitmap-ul corespunzator culorii alb va avea 1 pe pozitiile 1, 3, 7, 17, cel corespunzator culorii negru va avea 1 pe pozitiile 2, 8, 18, etc. De exemplu, pentru aflarea numarului de masini albe se va executa interogarea:
SELECT COUNT(*) FROM masina
WHERE culoare = 'alb';
Un index de tip bitmap poate procesa foarte eficient o astfel de interogare prin simpla numarare a valorilor 1 din bitmap-ul corespunzator valorii alb.
Un index de tip bitmap se creeaza folosind comanda create index cu optiunea bitmap, de exemplu:
create bitmap index culoare_ind on masina(culoare);
Spre deosebire de indecsii traditionali de tip arbore B*, folosirea indecsilor de tip bitmap se recomanda atunci cand:
numarul de valori distincte ale coloanei indexate este relativ mic (coloana are cardinalitate mica); de exemplu, in cazul unei coloane ce contine starea civila sau sexul unei persoane.
majoritatea interogarilor contin combinatii multiple de conditii WHERE ce implica operatorul OR
In acest caz, indecsii de tip bitmap pot avea o dimensiune mult mai mica decat indecsii de tip arbore B*. Pe de alta parte insa, indecsii de tip bitmap sunt ineficienti in cazul unor coloane cu numar mare de valori.
3 Tabele organizate pe baza de index
Tabelele organizate pe baza de index (index-organised tables) sunt o noutate adusa de versiunea Oracle 8. Un tabel organizat pe baza de index difera fata de un tabel obisnuit prin faptul ca datele tabelului sunt stocate in indexul asociat. Ori de cate ori se vor face modificari asupra datelor din tabel, precum adaugarea de noi randuri, modificarea sau stergerea randurilor existente, se va modifica doar indexul.
Mai exact, un tabel organizat pe baza de index este ca un tabel obisnuit avand un index de tip arbore B* pe una sau mai multe coloane, dar in loc de a folosi spatii separate de stocare pentru tabel si index, Oracle foloseste doar un singur index de tip B*, care contine atat valorile coloanelor indexate, cat si valorile celorlalte coloane pentru randul corespunzator. Deci, in loc ca fiecare intrare a indexului sa contina valoarea coloanei sau coloanelor indexate si valoarea ROWID pentru randul corespunzator, ea contine intreg randul. Coloana sau coloanele dupa care se face indexarea sunt cele care constituie cheia primara a tabelului. Din aceasta cauza, tabelele organizate pe index sunt eficiente pentru accesarea datelor prin intermediul cheii primare sau un prefix valid al acesteia.
Un tabel organizat pe baza de index poate fi manipulat de catre aplicatii la fel ca un tabel obisnuit, folosind comenzi SQL. Diferenta consta in faptul ca in cazul tabelului organizat pe baza de index, toate operatiile sunt efectuate numai asupra indexului.
Urmatorul tabel rezuma diferentele cele mai importante dintre un tabel obisnuit si un tabel organizat pe baza de index.
Tabel Obisnuit |
Tabel organizat pe baza de index |
ROWID identifica in mod unic un rand; specificarea cheii primare este optionala. |
Cheia primara identifica in mod unic un rand; specificarea cheii primare este obligatorie. |
Are coloana implicita ROWID |
Nu are coloana implicita ROWID |
Accesul la date se face prin intermediul ROWID |
Accesul la date se face prin intermediul cheii primare. |
Permite definirea de indecsi pentru coloane care nu fac parte din cheia primara. |
Nu permite definirea de indecsi pentru coloane care nu fac parte din cheia primara. |
Permite definirea constrangerii UNIQUE si a triggerelor. |
Nu permite definirea constrangerii UNIQUE, dar permite definirea triggerelor. |
Poate fi stocat intr-un cluster continand alte tabele. |
Nu poate fi stocat intr-un cluster continand alte tabele. |
Poate fi partitionat. |
Nu poate fi partitionat. |
Principalele avantaje ale tabelelor organizate pe baza de index sunt urmatoarele:
Se reduce timpul de acces la date prin interogari care folosesc ca termen de comparatie coloanele indexate
Se reduce spatiul de stocare datorita faptului ca nu mai este creat un index suplimentar pentru cheia primara a tabelului.
4. Crearea tabelelor organizate pe baza de index
Pentru a crea un tabel organizat pe baza de index, se foloseste comanda SQL CREATE TABLE cu specificatia ORGANIZATION INDEX. La crearea unui tabel organizat pe baza de index, trebuie neaparat specificata cheia primara a tabelului. In plus, se pot folosi clauzele OVERFLOW THRESHOLD si INCLUDING prezentate mai jos, care sunt optionale.
O intrare dintr-un index de tip arbore B* este de obicei destul de mica, constand dintr-o pereche (valoare indexata, ROWID). Pe de alta parte insa, intr-un tabel organizat pe baza de index, intrarile din indexul arborelui B* corespunzator pot fi foarte mari deoarece ele constau dintr-o pereche (cheie_primara, coloane_secundare), adica un rand intreg. Daca acestea sunt foarte mari, se poate ajunge la situatia in care fiecare nod frunza sa contina doar un singur rand sau o portiune de rand, distrugandu-se astfel densitatea indexului de tip arbore B*.
Pentru a evita aceasta problema, la crearea unui tabel organizat pe index se poate folosi clauza OVERFLOW, care specifica un spatiu tabel de depasire (OVERFLOW TABLESPACE). Alaturi de aceasta clauza se mai poate specifica si o valoare de prag (PCTTHRESHOLD). Valoarea de prag este specificata ca procent din marimea unui bloc. Daca dimensiunea randului depaseste valoarea de prag specificata, atunci coloanele care nu fac parte din cheia primara pentru randurile care depasesc valoarea de prag vor fi stocate in spatiul tabel de depasire specificat. In acest caz, intrarile din index vor contine perechea (cheie_primara, capat_rand), unde capat_rand contine partea de inceput a restului de coloane; acesta este exact ca o portiune normala de rand, cu exceptia faptului ca face referinta la portiunea ramasa de rand, care este stocata in spatiul tabel de depasire. Daca nu este specificata clauza OVERFLOW, atunci toate liniile care depasesc valoarea de prag sunt eliminate complet si nu mai sunt inserate in tabela organizata pe index.
Clauza INCLUDING, daca este specificata, determina coloana care va imparti tabelul in portiunea de index si portiunea de depasire. Fiecare coloana dupa coloana INCLUDING este stocata in portiunea de depasire a tabelului organizat pe index.
Deci, sintaxa comenzii CREATE TABLE pentru un tabel organizat pe index este urmatoarea:
CREATE TABLE nume_tabel
nume_coloana tip_data PRIMARY KEY )
ORGANIZATION INDEX
TABLESPACE spatiu_tabel
[PCTTHRESHOLD intreg
[INCLUDING nume_coloana
[OVERFLOW TABLESPACE spatiu_tabel_depasire
CREATE TABLE carte
(serie VARCHAR2(5),
numar NUMBER(7),
titlu VARCHAR2(20),
cod_autor VARCHAR2(10),
editura VARCHAR2(10),
descriere VARCHAR2(200),
CONSTRAINT pk_carte PRIMARY KEY (serie, numar))
ORGANIZATION INDEXED
TABLESPACE ts_alfa
PCTTHRESHOLD 40
INCLUDING editura
OVERFLOW TABLESPACE ts_beta;
Politica de confidentialitate | Termeni si conditii de utilizare |
Vizualizari: 3242
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved