Mikrozadanie 14

backback

Treść

W bazie danych są następujące tabele:

Zamowienie (
  nr VARCHAR(10) PRIMARY KEY, 
  klient VARCHAR(20)
) 
Pozycja(
  zam VARCHAR(10) REFERENCES Zamowienie,
  nr VARCHAR(3),
  towar VARCHAR(20),
  ilosc NUMBER(8),
  CONSTRAINT pk PRIMARY KEY (zam, id)
)

W takiej bazie danych ma zostać wykonane następujące zapytanie:

SELECT z.klient, p.towar
  FROM Zamowienie z, Pozycja p  
  WHERE z.nr = p.zam AND ilosc > ALL (SELECT ilosc FROM Pozycja p1  
                                      WHERE p1.zam = p.zam AND p1.towar <> p.towar);  

Przyjmijmy, że w pamięci operacyjnej mieści się 100 bloków, tabela Zamowienie ma 50.000 wierszy i zajmuje 1.000 bloków, a tabela Pozycja ma 1.000.000 wierszy i zajmuje 10.000 bloków. Zaproponuj jak najlepszy plan wykonania tego zapytania i oszacuj sumaryczną liczbę bloków przeczytanych i zapisanych na dysku. Można założyć istnienie dowolnych struktur pomocniczych.

Wzorcówka

Klastrujemy tabelę Pozycja po parze (zam, ilosc) i tworzymy indeks, który wskazuje na końce zamówień i trzyma w sobie informację (zam, towar), gdzie towar odpowiada dokładnie poszukiwanym nazwom towarów dla każdego zamówienia. Ten indeks obejmie około 1.0001.000 bloków, bo tyle jest różnych zamówień. Zamowienie klastrujemy po nr. Teraz możemy liniowo zjoinować informacje z indeksu z odpowiednim zamowieniem i dodać nazwę klienta. Koszt to przeczytanie całego najniższego rzędu indeksu i całej tabeli Zamowienie plus wypisanie wyniku, czyli 2.000+X2.000 + X. Można spokojnie założyć, że XX to od 1.0001.000 do 2.0002.000 bloków.

Rozwiązanie bardziej na palcach:

Zakładamy indeks sklastrowany na Zamowienie.nr oraz Pozycja.zam. W ten sposób możemy ładować Pozycje razem z Zamowieniami w rosnacej kolejnosci id, a w pomocniczym bloku pamięci trzymać największą do tej pory znalezioną ilosc oraz towar. Korzystamy jedynie z tego, że dane są posortowane i czytamy obie tabele raz, więc kosztuje nas to 1.000+10.000+X1.000 + 10.000 + X.

Uwagi

backback