Oppgave 16.7.1 I min bok er B(R) = 500, T(R) = 5000, V(R, a) = 50, V(R, b) = 1000, V(R, c) = 5000, og V(R, d) = 500. Løsningsforslaget nedenfor er med disse tallene. I boken til gruppelærerne er B(R) = 1000 og V(R, a) = 20. Så her kan svarene variere... Tupler per blokk: 5000/500=10 a) a=1 har 5000/50=100 forventede tupler. b=2 har 5000/1000=5 forventede tupler. c=>3 har 5000/3=1667. Vi har clusterindeks på a, så tabellen er sortert på a, og via den indeksen kan vi lese inn de 100 tuplene på 10 blokker (tuplene ligger etter hverandre), og så filtrere på øvrige betingelser. Kostnad 10. For b=2 har vi 5 tupler, men de kan ligge hvor som helst, worst case i 5 forskjellige blokker. Kostnad 5. For c=>3 er forventet antall tupler skyhøyt, og selv tettpakket er det 17 blokker å hente. Indeks på b er beste lesemetode, kostnad 5. b) a=1 har fremdeles 100 tupler. for b<2 og c>3 er det 1667. Beste lesemetode blir da indeks på a, deretter filter. Kostnad 10. c) a=1 er 100 tupler, b=2 er 5 tupler, d=3 er 5000/500=10 tupler. Siden vi kun har clusterindeks på a, blir regnestykker som i oppgave a), og indeks på b er beste metode, kostnad 5. For indeks på d blir kostnad 10, siden de tuplene kan ligge alle i hver sin blokk. -- Spørringene under er svar på følgende oppgave: Finn antall deltagere i hver deltagelsestype (parttype) per film blant kinofilmer som har "Lord of the Rings" som del av tittelen (hint: kinofilmer har filmtype 'C' i tabellen filmitem). Skriv ut filmtittel, deltagelsestype og antall deltagere. Se på spørreplanen til spørringen under, samt varianten med aggregeringen pushet "inn". Hvordan blir de eksekvert, og hvorfor lønner det seg ikke å pushe aggregeringen inn i dette tilfellet, i alle fall på denne måten? select count(personid), film.title, parttype from filmitem join film on filmitem.filmid=film.filmid join filmparticipation ON filmparticipation.filmid = film.filmid where film.title LIKE '%Lord of the Rings%' and filmitem.filmtype = 'C' group by film.filmid, film.title, parttype; --denne er litt tung, bruk explain uten analyze for å slippe venting. select ant, film.title, parttype FROM (select count(personid) as ant, parttype, filmid as fpfid FROM filmparticipation GROUP BY parttype, filmid) as aggparttype join film ON film.filmid=fpfid join filmitem ON filmitem.filmid = film.filmid where film.title LIKE '%Lord of the Rings%' and filmitem.filmtype = 'C'; For den første planen, merk at det er en parallell plan, med to workers. De gjør en dobbel loop join, etterfulgt av sortering og en sorteringsbasert aggregering (group aggregate). Grunnen til nested loop join er at vi har indekser å bruke. film-tabellen leses inn seksensielt, og fra de andre tabellene slår man opp via indeks. Den forventer å finne få tupler fra film som matcher betingelsen på title, derfor velger den en slik strategi. Group i stedet for hash aggregate tror jeg den velger fordi da er det lett å samle hver av de to arbeidernes resultater (de er begge sortert, og kan merges uten ekstra kostnad. Med hashing er det ikke så lett å ta to hashtabeller og merge dem. For den andre planen må den gjøre aggregering først, og det blir dyrt, fordi det er en veldig stor tabell, og vi må ta alle tuplene (alle betingelser er på de andre tabellene, så vi får ikke filtrert noe på filmparticipation).