Rychlejší aplikace i bez změn dotazů - 3.díl - vliv hromadných operací a shrnutí

V předchozích dvou dílech jsme si ukázali, jak lze vzorový příklad vkládání 100.000 záznamů zrychlit, pokud se nám podaří minimalizovat počet commitů a začít používat v dotazech vázané proměnné. Těmito dvěma změnami jsme původní čas 167 sekund snížili postupně na 105 a následně na 19 sekund. Ke slibovanému osmdesátinásobnému zrychlení potřebujeme dosáhnout ještě cca desetinásobného zrychlení. Provedeme to tím, že se 100.000 jednotlivých operací pokusíme převést na menší počet hromadných operací.

4. Hromadné operace - klíč k rychlému zpracování dat

Občas vývojáři aplikací zapomínají na jeden důležitý fakt, a to že databázové systémy jsou stavěny pro hromadné zpracování dat. Změnu 50 záznamů specifikovaných podmínkou v jedné operaci provedou databáze obvykle výrazně rychleji, než když stejných 50 změn provedete jednu po druhé samostatnými SQL dotazy. To platí bez rozdílu, ať je logika napsána jako uložená procedura, nebo je implementována na klientovi. Jak ale můžeme tuto skutečnost využít v případě vkládání dat přes klientskou aplikaci? Odpovědí mohou být dávky, nebo případně předání vstupních hodnot hromadně formou pole, pokud to vámi používaný interface podporuje. Ukážeme si vliv použití dávky o velikosti 1.000 záznamů (test 4a) a srovnáme výsledky s velikostí dávky 100 (4b) a 10.000 (4c) záznamů.

void davky(Connection conn, String dalsidata) throws SQLException {
PreparedStatement stmt;
String popis;
int batchSize=1000;
int batchCount=100;
stmt=conn.prepareStatement(
"INSERT INTO mojeTab (datum,popis,dalsidata) VALUES(SYSDATE,?,?)");
for(int batchNo=0;batchNo for(int i=0;i popis="Muj popis c." + (i+(batchNo*batchSize));
stmt.setString(1,popis);
stmt.setString(2,dalsidata);
stmt.addBatch();
}
stmt.executeBatch();
}
stmt.close();
conn.commit();
}

V tomto případě neprobíhá komunikace s databázovým serverem během vložení každého záznamu, ale až hromadně při spuštění dávky metodou executeBatch. A doba zpracování? Ve všech třech případech trvalo vložení 100.000 záznamů cca 2 sekundy. Díky dávkám jsme tedy oproti předchozímu příkladu dosáhli dalšího skoro desetinásobného zrychlení.

Statistika3a. Vázané proměnné, sdílený PreparedStmt.4a. Dávka
1000
Úspora4b. Dávka 1004c. Dávka 10.000
Čas a CPU
Dosažený čas [s]19288%22
CPU used by this session (Spotřeba CPU) [s]5,60,889%0,80,7
Komunikace po síti
Bytes received via SQL*Net from client (komunikace client>server) [bytes]27 789 38523 181 31817%23 127 25123 249 775
Bytes sent via SQL*Net to client(komunikace server>klient) [bytes]7 196 3727 665100%72 1151 095
SQL*Net roundtrips to/from client(síťové operace) [počet operací]100 002102100%1 00212
Čtení a zápis dat
Session logical reads (Logické čtení) [počet operací]130 27435 89672%35 842 35734
Db block changes (Změny datových bloků) [počet operací]219 29426 22988%26 09326 104
Redo size (Objem dat zapsaný do redo logů) [bytes]48 262 59226 707 59645%26 589 60426 774 392
Undo change vector size (Objem dat zapsaný do undo tblspc.) [bytes]6 402 099620 53490%620 214617 014

Statistiky ukazují očekávanou významnou úsporu síťové komunikace. Všimněte si, že zavedení hromadného zpracování snížilo i spotřebu CPU na sedminu. Nejzajímavější ale je, že úspora se týká i všech čtecích a zápisových operací. Objem dat zapisovaných do Undo tablespace (undo change vector size) klesl dokonce na jednu desetinu.
Je zřejmé, že větší velikost dávky znamená menší množství zpráv putujících mezi databázovým klientem a serverem, na dobu zpracování ani jiné sledované statistiky však v tomto konkrétním případě již různá velikost dávky neměla zásadní vliv. Předpokládám ale, že by vliv velikosti dávky na dobu odezvy byl větší, pokud by klient a server komunikovali přes síť s delší latencí.


Závěr

Je zřejmé, že zrychlení, kterého dosáhneme zavedením postupů popsaných v těchto třech dílech se bude u různých aplikací lišit, ne vždy se musí doba zpracování zkrátit zrovna 83 krát. Obvykle ale jde opravdu o více než znatelné zrychlení. V některých situacích samozřejmě nebudete schopni použít všechny uvedené postupy. Cílem této série článků ale bylo ukázat jak obrovský dopad tato opatření mohou mít, abyste se tak mohli lépe rozhodnout, zda by i ve složitějších případech, kdy na první pohled aplikace podobných technik není možná, nestálo za to více uvažovat o tom, jestli úloha nejde nějak transformovat tak, aby se tyto techniky daly využít. A pokud se rozhodnete to neudělat, abyste měli představu o co tím přicházíte.

dobaZpracovani.JPGVraťme se nyní ještě jednou ke statistikám z jednotlivých kroků a srovnejme si výchozí stav z prvního dílů této třídílné minisérie se stavem dosaženým po odstranění neefektivních commitů, zavedení vázaných proměnných, využití cachování PreparedStatement a dávkového zpracování. Nejde jen o to, že jsme dobu odezvy postupně zkrátili 83 krát. Nižší spotřeba zdrojů se zákonitě projeví i v nižších nárocích na infrastrukturu a tím pádem i potenciálně nižších pořizovacích nákladech pro vás či vaše zákazníky.

Statistika1. Základ2. Commit 1x3a. Vázané proměnné, sdílený PreparedStmt.4a. Dávka 1.000Úspora oproti výchozímu stavu
Čas a CPU
Dosažený čas [s]16710519299%
CPU used by this session (Spotřeba CPU) [s]103865,60,899%
Komunikace po síti
Bytes received via SQL*Net from client (komunikace client>server) [bytes]35 889 11634 189 13827 789 38523 181 31835%
Bytes sent via SQL*Net to client (komunikace server>klient) [bytes]7 996 0197 296 3657 196 3727 665100%
SQL*Net roundtrips to/from client (síťové operace) [počet operací]200 001100 002100 002102100%
Čtení a zápis dat
Session logical reads (Logické čtení) [počet operací]715 358426 928130 27435 89695%
Db block changes (Změny datových bloků) [počet operací]421 819219 282219 29426 22994%
Redo size (Objem dat zapsaný do redo logů) [bytes]75 749 02648 221 63248 262 59226 707 59665%
Undo change vector size (Objem dat zapsaný do undo tblspc.) [bytes]12 669 4686 401 9846 402 099620 53495%
Optimalizace dotazů
Parse time elapsed (Doba parsování dotazů) [s]807400100%
Parse time CPU (CPU spotřebované parsováním) [s]807400100%
Opened cursors cumulative (Otevřené kurzory) [počet]100 101100 0899286100%
Parse count (hard) (Úplná optimalizace dotazů) [počet]100 002100 00011100%
Parse count (total) (Optimalizace dotazů celkem) [počet]100 100100 0899286100%


LogicalIO.JPGPočet čtecích a zápisových operací v datových souborech klesl 18 krát, objem dat zapsaných do undo tablespace dokonce 20 krát a objem generovaných redologů klesl na třetinu. Nižší počet operací i menší objem dat může znamenat, že budete muset zátěž rozkládat mezi menší počet fyzických disků a možná si vystačíte i s méně výkonným diskovým polem.

Objem dat přenášených po síti se snížil skoro na polovinu a množství síťových operací dokonce skoro na dvoutisícinu. To pro vás může znamenat méně problémů, pokud se váš zákazník či uživatel bude připojovat k aplikaci po síti s nižší přenosovou rychlostí či vyšší latencí. A na závěr tu samozřejmě máme jednu drobnost - 134 krát snížená spotřeba CPU. Možná tak vystačíte s menším počtem CPU v serveru, což vás potěší nejen při nákupu hardware, ale i při nákupu licencí Oracle Database. V souvislosti s tím mne ale napadá - opravdu mám zrovna já rozdávat takové rady?

Comments:

Post a Comment:
  • HTML Syntax: NOT allowed
About

Česky o všem co se točí kolem Oracle Database.

Autoři:

Patrik Plachý
Technology Sales Consultant

David Krch
Principal Consultant
Oracle Expert Services

Oracle Czech

Search

Archives
« duben 2014
PoÚtStČtSoNe
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    
       
Today