Izvještaj se generira pola sata, a dotle nitko ne može raditi? Zašto se to događa i kako riješiti
Jedan izvještaj se pokrene i nitko drugi ne može raditi? Zašto izvještaji usporavaju cijelu poslovnu aplikaciju, što to košta i pet rješenja od najjeftinijeg.
Vlado Pandžić · Osnivač · Senior .NET arhitekt
Objavljeno · 5 min čitanja
Zadnji radni dan u mjesecu. U osam ujutro financije pokrenu mjesečni izvještaj o prodaji. Pet minuta kasnije skladište ne može ispisati otpremnice, a prodaja zove informatičara da je sustav pao. Nitko ne zna što se događa, pa netko u financijama ponovno klikne “Generiraj”. Sad se vrte dva izvještaja.
Ovaj scenarij je izmišljen, ali prepoznat će ga gotovo svaka tvrtka koja ima svoju poslovnu aplikaciju. I obično to nije problem servera. Problem je u tome kako su izvještaji napravljeni.
- 08:00Financije pokrenu mjesečni izvještaj
- 08:05Skladište ne može ispisati otpremnice
- 08:20Prodaja javlja da je sustav pao
- 08:25Netko ponovno pokrene izvještaj
- 08:40Izvještaj istekne i kreće ispočetka
Zašto jedan izvještaj zaustavi sve
Zamislite trgovinu koja se zatvori zbog inventure dok kupci još stoje u redu na blagajni. Poslovne aplikacije to rade stalno:
- Izvještaji i svakodnevni rad koriste istu bazu. Izvještaj čita milijune redaka, a isti disk, memorija i procesor istovremeno moraju služiti skladište, prodaju i sve ostale.
- Čitanje koči pisanje. Na SQL Serveru dugo čitanje po zadanim postavkama može zadržati svakoga tko želi mijenjati iste podatke, i obrnuto. Izvještaj čeka skladište, skladište čeka izvještaj.
- Sve se računa ispočetka. Da bi dobio zbroj za prošli mjesec, izvještaj svaki put zbroji pet godina računa. Dok je podataka bilo malo, nitko to nije primijetio.
- Aplikacija sve povuče u memoriju. Umjesto da baza zbroji i vrati stotinu redaka, aplikacija učita sve podatke i zbraja sama.
- Korisnik čeka pred ekranom. Izvještaj radi dok preglednik čeka. Kad preglednik odustane, čovjek klikne ponovno, i sad se isti posao radi dvaput.
Koliko to košta
Jednostavan primjer s izmišljenim, ali realnim brojkama:
| Ljudi koji rade u aplikaciji | 40 |
| Izgubljeno vrijeme svaki put kad izvještaj uspori sve | 30 minuta |
| Koliko se često to dogodi (kraj mjeseca, PDV, sastanak uprave, ad hoc) | 4 puta mjesečno |
| Izgubljenih sati mjesečno | 80 |
| Uz 30 € po satu | 2.400 € mjesečno, gotovo 29.000 € godišnje |
To je samo ono što se može izbrojiti. Na to dođu isporuke koje kasne, financije koje ostaju navečer da nikome ne smetaju i odluke donesene na starim brojkama jer se nitko ne usudi pokrenuti izvještaj u radno vrijeme.
Rješenja, od najjeftinijeg prema većem
Dobra vijest je da vam rijetko treba novi sustav. Redoslijed je najčešće isti:
| Rješenje | Što znači | Trud |
|---|---|---|
| 1. Upit i indeksi | Izvještaj bazu pita na pravi način i dobije samo ono što mu treba | Dani |
| 2. Čitanje ne koči pisanje | Postavka baze da izvještaj i skladište prestanu čekati jedno drugo | Sati do dana, s testiranjem |
| 3. Izvještaj radi u pozadini | Korisnik klikne, nastavi raditi i dobije mail s linkom kad je izvještaj gotov | Dani |
| 4. Unaprijed izračunati zbrojevi | Zbrojevi po danu, kupcu i artiklu računaju se jednom, noću | Dani do tjedana |
| 5. Zasebna kopija za izvještaje | Izvještaji čitaju iz kopije baze, svakodnevni rad koristi original | Dani, ovisno o platformi |
1. Upit i indeksi. Ovo je gotovo uvijek prvi korak, a često i zadnji. Izvještaj koji čita cijelu tablicu jer nedostaje indeks, ili izvještaj koji za jednu stranicu šalje tisuće upita, može pasti s pola sata na manje od minute. Najčešće uzroke opisali smo u člancima o sporim aplikacijama i performansama EF Corea.
2. Čitanje ne koči pisanje. SQL Server ima opciju (Read Committed Snapshot Isolation) s kojom izvještaj čita dosljednu sliku podataka, a da pritom ne zaustavlja nikoga tko piše. U Azure SQL Databaseu je po zadanim postavkama uključena, a na vašem vlastitom SQL Serveru isključena. To je jedna postavka, ali mijenja kako se baza ponaša, pa se testira prije nego ide u produkciju.
3. Izvještaj radi u pozadini. Umjesto da čovjek čeka pred ekranom, izvještaj ide u red i generira se kad ima kapaciteta, jedan po jedan. Čovjek dobije mail kad je gotov. Nema više dvostrukih klikova i isteka, a najteži izvještaji mogu pričekati večer.
4. Unaprijed izračunati zbrojevi. Većina izvještaja pita isto: koliko, po danu, kupcu, artiklu ili regiji. Te zbrojeve možete izračunati jednom, noću ili nakon svake promjene, pa izvještaj onda čita nekoliko tisuća redaka umjesto nekoliko milijuna.
5. Zasebna kopija za izvještaje. Ako ste na Azure SQL Databaseu u Premium ili Business Critical razini, već plaćate kopiju baze samo za čitanje koju aplikacija ne koristi. Izvještaji se tamo šalju jednom postavkom u connection stringu:
"ConnectionStrings": {
"App": "Server=tcp:company.database.windows.net;Database=Erp;...",
"Reports": "Server=tcp:company.database.windows.net;Database=Erp;ApplicationIntent=ReadOnly;..."
}
Svakodnevni rad koristi App, izvještaji koriste Reports i više se ne otimaju za iste resurse. Podaci na kopiju mogu stići trenutak kasnije nego na original, što za mjesečni izvještaj nije važno. Na vlastitom SQL Serveru moguće je nešto slično, ali ovisi o ediciji i licenciranju, pa se to prvo provjeri.
Kojim redom
- MjerenjeKoji izvještaji bole i zašto
- UpitiIndeksi i manje poziva
- PozadinaNitko ne čeka pred ekranom
- Zbrojevi i kopijaSamo ako još treba
Mjerenje je prvo, kao i uvijek. Ono pokaže koja tri ili četiri izvještaja rade većinu problema, a često je posla manje nego što se činilo. Tek kad su upiti sređeni, ima smisla razgovarati o obradi u pozadini, unaprijed izračunatim zbrojevima i zasebnoj bazi. Novi alat za izvještavanje ili jači server dolaze zadnji, ako uopće.
Kako mi radimo
ProCoding je .NET studio iz Splita. Spori izvještaji i baza koja koči sve ostale upravo su ono što popravljamo: u .NET aplikacijama, SQL Serveru i Azure SQL-u, od upita i indeksa do obrade u pozadini i kopija baze samo za čitanje. Više o tome što radimo na Azureu je na stranici Azure za .NET aplikacije.
Počinjemo mjerenjem vaših izvještaja i dobivate popis uzroka i rješenja poredanih po tome što se najviše isplati. Nakon toga ih popravljamo mi ili vaš tim, kako vam više odgovara. Prvi korak je besplatni razgovor od 30 minuta.
Izvori
- Read queries on replicas (read scale-out), Microsoft Learn
- SET TRANSACTION ISOLATION LEVEL, Microsoft Learn
- Background tasks with hosted services in ASP.NET Core, Microsoft Learn
Ovaj članak služi općem informiranju i nije pravni, porezni, financijski ni drugi stručni savjet. Scenariji, primjeri i izračuni su ilustrativni. Uvjeti korištenja i odricanje od odgovornosti.