Indeksy bitmapowe łączeniowe są
wykorzystywane głównie w hurtowniach danych, często wraz z Star
Transformation. Indeksy łączeniowe pojawiły się z wersją 9i
Oracle.
Takie indeksy pozwalają zmniejszyć
ilość wykonywanych kosztownych operacji łączenia tabel. Taki
indeks będzie przechowywał wcześniej wyliczone wyniki łączenia.
Podczas zapytania z użyciem łączenia, będzie można użyć danych
z indeksu, zamiast wykonywać operację łączenia.
W indeksach bitmapowych każda unikalna
wartość w kolumnie jest powiązana z mapą bitową, w której każdy
bit reprezentuje jeden wiersz w tabeli. 1 oznacza że wartość
występuje w danym wierszu, 0 że nie występuje. Indeksy takie
zakłada się na kolumnach o małym zróżnicowaniu. Nie powinno się
ich stosować na tabelach często modyfikowanych (tzn. na tabelach w
których pojawiają się często nowe wiersze, kasowane są stare,
lub zmienia się wartość kolumny na której założony jest taki
indeks). Wiąże się to z obciążeniem wynikającym z konieczności
aktualizacji takiego indeksu.
Przyjrzyjmy się teraz praktycznemu
zastosowaniu tego typu indeksów. Pracujemy na schemacie SH , który
jest schematem przykładowym dostarczanym przy instalacji bazy.
Wystarczy ten schemat odblokować. Sprawdźmy plan wykonania
zapytania wymagającego łączenia tabel customers i
sales. Większość
obciążenia generowane jest przez obciążenia wynikającego z
samego łączenia, lub operacji z łączeniem związanych:
select count(*) from sales join
customers using(cust_id) where cust_city='Yokohama';
Założymy teraz indeks bitmapowy
łączeniowy i porównamy wyniki. Najprostszy taki indeks mógłby
zawierać samo tylko złączenie:
create bitmap
index lacz1 on sales(c.cust_id)
from sales s ,
customers c
where
s.cust_id=c.cust_id local;
Słowo local na
końcu jest wymagane wyłącznie w przypadku tabel partycjonowanych.
W tym jednak przypadku stosujemy warunek na kolumnie
cust_city, więc najlepiej byłoby gdyby ta kolumna również
znalazła się w indeksie. W innym wypadku, w związku koniecznością
dostępu do danych z tej kolumny, CBO decydowałby o nie używaniu
naszego nowego indeksu. Stworzymy więc indeks zawierający nie tylko
łączenie, ale również kolumnę cust_city z tabeli customers:
create bitmap
index lacz1 on sales(customers.cust_city)
from sales ,
customers
where
sales.cust_id=customers.cust_id local;
Gdybyśmy dostali
komunikat o braku klucza głównego , należy uruchomić poniższe
polecenie:
alter table
customers enable constraint customers_pk;
Dotyczy to jednak jedynie powyższego
przykładu w schemacie SH. Indeksy
bitmapowe łączeniowe wymagają, by łączenie następowało z
użyciem klucza głównego, a ten w tabeli curstomers
istnieje, ale jest wyłączony. Porównajmy teraz plany wykonania
zapytania i ich koszty:
Znacznie mniejszy koszt wykonania tego
zapytania z użyciem indeksu bitmapowego łączeniowego, wynika z
faktu, że nie ma konieczności wykonywania łączenia ze sobą tabel
i związanych z tym odczytów danych które są do tego potrzebne.
Informacje o połączeniu są przechowywane w indeksie. Oczywiście w
przypadku np. dodania wiersza do tabeli sales, trzeba będzie znaleźć
wszystkie odpowiedniki po stronie drugiej tabeli i zaktualizować
indeks. To wiąże się z generowaniem sporego obciążenia przy
ładowaniu danych.
Weźmy teraz troszkę bardziej
skomplikowany przypadek. Łączymy ze sobą trzy tabele liniowo, przy
czym warunek filtrowania wierszy stosujemy na ostatniej.
select count(*) from sales join
customers using(cust_id)
join countries using (country_id)
where country_name='Poland';
Ponownie pojawia nam się spore
obciążenie wynikające z potrzeby łączenia tabel. Tworzę więc
indeks bitmapowy łączeniowy, tym razem na łączeniu ze sobą
trzech tabel:
create bitmap
index lacz2 on sales(countries.country_name)
from sales ,
customers, countries
where
sales.cust_id=customers.cust_id
and
customers.country_id=countries.country_id
local;
Sprawdźmy jak prezentuje się nam plan
wykonania teraz:
Ograniczenia indeksów bitmapowych
łączeniowych
- nie da się założyć takiego indeksu na tabeli tymczasowej , ani tabeli typu IOT.
- W klauzuli FROM nie można wymienić tej samej tabeli dwukrotnie
- nie może to być indeks funkcyjny
Brak komentarzy:
Prześlij komentarz