Materialized views in MySQL
Včasih pridemo do problema, ko želimo na svoji spletni predstavitvi objaviti kakšno statistiko, ki zahteva zelo požrešno poizvedbo, rezultat le-te pa je bolj kot ne zelo statičen. Zaradi požrešnosti poizvedbe in dolgega časa izvajanja se nam zmanjša odzivnost strani. Materialized views so lahko v takih primerih silno uporabna zadevščina, tukaj bom na kratko napisal, kako v MySQL, ki jih sicer ne podpira, vnesti vsaj nekaj okusa po njih.
Kaj točno so materialized views? So shranjeni podatki, ki vsebujejo predobdelane rezultate, ki smo jih pridobili preko SQL SELECT poizvedbe. Ker so podatki vnaprej izračunani, dobimo rezultate poizvedbe hitreje.
V katerem konkretnem primeru bi nam materialized views prišli prav? Enostavni primeri so recimo člankarski portal, kjer želimo prikazati seznam zadnjih nekaj člankov, potem recimo portal, kjer uporabniki ocenjujejo druge uporabnike, želimo pa prikazati nekaj najbolje ocenjenih, in še in še.
Recimo, da imamo naslednjo tabelo člankov:
Če imamo v gornji tabeli manjše število podatkov, zadeva še nekako gre, kaj pa se zgodi, ko želite prikazati zadnjih 10 člankov, ko jih imate v tabeli že 100.000? Kakšen query ponavadi napišemo za to?
Kaj se dogaja, ko izvedemo naslednji query? Poskusimo naslednje na tabeli s 100.000 zapisi:
Poizvedba povzroči obdelavo vseh 100.000 zapisov iz tabele skupaj s sortiranjem, kar seveda lahko traja kar precej časa. Želeli smo pa le rezultat, ki vsebuje 10 zapisov! Če želimo rezultat te poizvedbe prikazovati pri vsakem prikazu naše strani, imamo pa lahko že kar problem, kaj šele, če je takih poizvedb več.
Kaj storiti? Pripravimo vmesno tabelo, ki bo vsebovala samo seznam zadnjih nekaj objavljenih člankov.
Dobro, ampak ta tabela je prazna, kdo jo bo polnil? Napišemo najprej naslednjo proceduro:
Sedaj lahko proceduro zaženemo:
V tabeli clanki_zadnji imamo sedaj 10 zapisov. Super, ampak ali bomo to vedno morali poganjati ročno? Ne bo potrebe, zato imamo triggerje. Kreiramo tri triggerje, po enega za INSERT, UPDATE in DELETE:
Poskusite nekaj člankov dodati, brisati, spreminjati. Vsakič, ko naredite katerokoli od teh sprememb, se podatki v tabeli clanki_zadnji osvežijo.
Poglejmo si sedaj naslednjo analizo:
Rezultat je seveda veliko boljši, kot zgoraj. Potrebnih je bilo le 10 skokov, da smo prišli do željenega rezultata.
Za konec lahko kreiramo še view za zadnje članke:
in potem preprosto dostopamo do podatkov o zadnjih desetih člankih z naslednjo poizvedbo:
Tole je konec tega enostavnega primera uporabe materialized views, vsekakor bi z zadevo lahko počeli še vse kaj zahtevnejšega kot to, ampak za približno predstavo, kaj materialized views sploh so, in kako jih simulirati v MySQL, bo pa kar dovolj.
Domača naloga: kaj pa če članke pišemo vnaprej in želimo, da se med zadnjimi članki pojavijo šele, ko je polje objava manjše ali enako današnjemu datumu?