Goran Dumić
Autor:
Goran Dumić

Oracle guru

Paginacija podatkovnog skupa – nekonvencijalan pristup

Kad je riječ o poslovnim aplikacijama, prije ili kasnije na popisu zadataka svoje mjesto pronađu tražilice i paginacija, vrlo često i kao performansno usko grlo. Kako postoji puno načina izvedbe same paginacije, te zabluda koje se vežu uz mnoge od njih, pokušat ćemo iz perspektive baze podataka ponuditi jedan drugi pogled prema univerzalnom i efikasnom rješenju.

Ovaj članak se fokusira na aplikacije srednje veličine (složene forme za pretraživanje, nekoliko milijuna redova podataka i nekoliko stotina korisnika aplikacije). Predloženo rješenje snažno podupire mehanizam paginacije na strani baze podataka, za razliku od onog koji bi se odvijao na strani aplikacije i koji podrazumijeva korištenje biblioteka trećih strana. Razlog tomu je jednostavan - kontrolira izvedbe je na našoj strani. A ako se izvede na pravi način, efikasno izvlačenje podataka može biti ključ dobrih performansi u takvom složenom okruženju.

Zabluda #1
Zanimljivo, kad se govori o tražilicama, vrlo često se povlači pitanje dugog odziva aplikacije na određeni upit, a „u podacima ima samo X zapisa koji zadovoljavaju kriterije pretrage“. To je zapravo ekvivalent pitanju: „Samo je X kamenčića u moru, zašto ti potraga za njima dugo traje?“. Izvlačenje podatka/kamenčića nije razlog za brigu, ali potraga, tj. pretraga jest. I tu tražimo način da budemo efikasni.

Osnove – efikasnost bez zalihosti

Zabluda #2
O čemu se ovdje radi? Mnogi developeri zapravo koriste dva prolaza po pojedinoj pretrazi. Time nesvjesno stvaraju zalihost i utječu na vrijeme odziva, primijenjujući algoritam:

  1. primijeni parametre pretrage
  2. prebroji ukupan broj redaka koji zadovoljavaju uvjete
  3. ponovo primijeni parametre pretrage i dohvati sve kandidate
  4. razdijeli podatkovni skup na stranice, te ovisno o veličini stranice vrati rezultate za traženu stranicu

Zvuči poznato? Primijenimo ove korake na naš, stvarni svijet. Kada bi nam netko dao zadatak da u knjizi pronađemo retke koji spominju riječ „zalihost“, ekvivalentni koraci gornjeg pristupa bili bi:

  1. počnemo čitati knjigu od korica do korica i bilježimo svaku pojavu navedene riječi (bez varanja, samo povećavamo brojač, ništa drugo)
  2. nakon toga čitamo knjigu ponovo i bilježimo širi kontekst (poglavlje, broj stranice i slično)
  3. podijelimo rezultate po stranicama i završimo izazov za traženu stranicu

Sad već zasigurno primijećujemo redundantnost ovog pristupa, na više razina. Za početak, održavamo kriterije (filtere) pretrage na dva mjesta u kodu – za „brojanje“ i za „širi kontekst“, tj. izlazne retke. Drugo i ključno – čitamo knjigu (barem) dva puta, što je neefikasno.


Savjet #1: Izlaznom skupu možemo pridodati ukupan broj redaka koji zadovoljavaju kriterije pretrage i time kompletno eliminiramo korak 2. Kolege aplikativci mogu uzeti bilo koji redak za prikaz ukupnog broja redaka u aplikaciji.

Savjet #2: Stavljanje rezultata nekoliko stranica u predmemoriju. Obzirom da većina korisnika podatke konzumira na povezan način (slijedno se kreće po stranicama), aplikaciji možemo vratiti rezultate za N stranica i prepustiti aplikaciji razbijanje po pojedinoj stranici. Pretpostavka je kako će većina korisnika odustati nakon tih X stranica, pa možda neće biti potrebe niti povlačiti dodatni skup podataka po ostalim stranicama. Pritom moramo imati na umu kako bilo kakvo memoriranje rezultata potencijalno više ne odražava stvarno stanje u bazi podataka, stoga se savjetuje manji skup memoriranja.

Izbjegavanje teških izračuna

Uočite kako još uvijek čitamo cijeli podatkovni skup (knjigu) iznova i iznova. Ne bi li nam bilo jednostavnije i brže (!) kada bismo mogli nakon X rezultata reći: u redu, ne trebamo dalje čitati, ovo će biti dovoljno rezultata. Ukupan broj rezultata je težak izračun upravo zbog toga što uvijek čitamo sve. Stoga, kad korisnici (i poslovni analitičari) zahtijevaju ukupan broj rezultata, prođite ovu listu pitanja:

  1. koja je poslovna vrijednost tog podatka i u koju svrhu se koristi ? Vrlo često ovo je samo „zgodna funkcionalnost“, ali zasigurno ne za izvještavanje u stvarnom vremenu
  2. uvedite pojam razumnog ograničenja rezultata, primjerice 10.000 zapisa, koji će drastično povećati odziv aplikacije i održavati jednostavnije planove izvođenja baze podataka
    Dakle, za svaki upit, korisnici mogu dobiti dva tipa ukupnog zbroja:
    • točan ukupni zbroj ukoliko je broj pogodaka < 10.000
    • za pogotke >= 10.000 možete dogovoriti univerzalnu poruku “prikazuje se prvih 10.000 rezultata” koji obično znače kako se moraju prilagoditi parametri pretrage kako bi se vratio razuman skup podataka. Ovo je osobito važno ukoliko je veličina stranice malena (npr. 10–50 pogodaka po stranici). Izračunajte koliko stranica korisnici moraju proći do razumnog ograničenja i iznesite to klijentu (obično svaka rasprava time završava)
  3. korištenje dinamičkog upita (s bind varijablama) za kreiranje idealnog upita za konretnu pretragu. To znači kako u upitu radimo upravo dovoljno relacija između tablica koliko nam je potrebno za pokrivanje parametara pretrage, te eliminiramo nepotrebne vezne entitete. Primjerice nećemo povezivati tablicu jezika koje osoba govori sve dok korisnik ne izabere taj filter u aplikaciji:

  4. usmjerimo bazu da bolje razumije zahtjev paginacije 


Korištenjem ključnih riječi FIRST_ROWS i ROWNUM  usmjeravamo plan izvođenja maksimizirajući performanse.

Nepoželjna paginacija na razini baze

Kada nam paginacija na razini baze ne bi predstavljala kvalitetno rješenje? Očito, baza se teško može mjeriti s dinamičkim sortiranjem kroz više stupaca. U tom slučaju, vratili bismo broj redaka unutar razumnog ograničenja, a paginaciju zasigurno ostavimo nekome drugome.

Preispitujte i dalje

Ne pristajte na kompromise kad je riječ o performansama. Nikome ne treba tražilica kojoj treba dvije minute da vrati rezultate. Stoga, da li je potrebno imati toliko opcionalnih parametara forme? Moraju li parametri biti padajuće liste s višestrukim odabirom ? Mogu li se eliminirati pretrage po vodećem zamjenskom znaku (%neka_vrijednost), koje se teško mogu optimizirati ?

I naposlijetku, uvijek definirajte barem jedan mandatorni parametar koji čini razliku i zbilja ograničava podatkovni skup, primjerice kategorija, zastavica (ne)aktivnosti, razni datumi i slično. Takvi atributi će otvoriti dodatne mogućnosti za optimizaciju na strani baze podataka (particioniranje, napredna indeksacija i slično), te omogućiti vašoj aplikaciji ispunjenje svih korisničkih očekivanja.

Popularne teme
.NET ABAP ADFS Agile Always On Anemic Model Angular Azure Backbone benchmark BI BI projekti Bootstrap building people business inteligence Business Intelligence Change Chrome CI CITCON Claims compile Continuous Delivery continuous deployment Continuous Integration CSR d3js data data visualization Data visualization alati DDD dekompozicija dependency injection dinamička forma dinamički parametri dinamički query distribuirani razvoj Domain-Driven design DOP društvena odgovornost edge-based video analytics Eliminating waste enkapsulacija enterprise razvoj softvera ERP ETL Excel FIORI Frontend game Geopackage GPKG GIS Git Groovy heat map HICCUPS Hichert HTML IBCS interoperability invision IoT IPSO izvještavanje java JavaFX Javascript Jazz Build Engine JBE Jenkins jquery jqueryui jsfiddle JVM Kaizen Kanban king KING ICT Kingovci Knockout kvaliteta lambde leadership Lean legacy code M language Management Maven Metodologija microservices Microsoft mobile Mobility mockups moć monday game NetWeaver network nodejs oblikovni obrasci OGC OKR open source optimizacija organizacija organizacijska struktura OutOfMemoryError outsourcing overengineering paginacija Performance performanse PERT PMI PMP; Agile; Project management; Scrum; KING ICT; razvoj; metodologija podatkovni skup pouzdanost Power BI Power Map Power Pivot Power Query Power View pretraga proces procjena Product Owner programming proizvod Project manager projektni plan radar Rational Team Concert razvoj tima refaktoriranje Release resize responsive charts REST retrospektiva Rich-Domain model Roko Roić rolling wave planning RTC SAP scale scatterplot chart Scrum scrum team scrum tim service boundaries single responsibility principle Single Sign-On smart metering SoapUI social responsibility softver Software software prototyping Software Testing Club Spring Boot SQL standard sustav videonadzora svg tdd Team team building team development Team Foundation Server tech tehnologije terminski plan Testing tim timesheet timovi Toggl.com touch transakcijski nadzor tražilica underengineering unit testing Uspjeh Visual Studio vodstvo vodstvo leadership moć društvena odgovornost DOP social responsibility CSR vođenje projekata WBS Web Zagreb STC

PRIJAVA NA NEWSLETTER

Najnovije novosti iz ICT svijeta