sql >> Databasteknik >  >> RDS >> Oracle

Prestandaöverväganden för temporär data i Oracle

Temporära tabeller är i praktiken desamma som tabeller i minnet tack vare cachning och asynkron I/O, och den temporära tabelllösningen kräver ingen overhead för konvertering mellan SQL och PL/SQL.

Bekräftar resultaten

Jämför man de två versionerna med RunStats, ser den temporära tabellversionen ut mycket värre. Allt skräp för den temporära tabellversionen i Run1, och bara lite extra minne för PL/SQL-versionen i Run2. Till en början verkar det som att PL/SQL borde vara den klara vinnaren.

Type  Name                              Run1 (temp) Run2 (PLSQL)         Diff
----- -------------------------------- ------------ ------------ ------------
...
STAT  physical read bytes                    81,920            0      -81,920
STAT  physical read total bytes              81,920            0      -81,920
LATCH cache buffers chains                  104,663          462     -104,201
STAT  session uga memory                    445,488      681,016      235,528
STAT  KTFB alloc space (block)            2,097,152            0   -2,097,152
STAT  undo change vector size             2,350,188            0   -2,350,188
STAT  redo size                           2,804,516            0   -2,804,516
STAT  temp space allocated (bytes)       12,582,912            0  -12,582,912
STAT  table scan rows gotten             15,499,845            0  -15,499,845
STAT  session pga memory                    196,608   19,857,408   19,660,800
STAT  logical read bytes from cache     299,958,272            0 -299,958,272

Men i slutet av dagen är det bara väggklockans tid som spelar roll. Både laddnings- och frågesteget går mycket snabbare med tillfälliga tabeller.

PL/SQL-versionen kan förbättras genom att ersätta BULK COLLECT med cast(collect(test_o(MOD(a, 10), '' || MOD(a, 12))) as test_t) INTO t . Men den är fortfarande betydligt långsammare än den temporära tabellversionen.

Optimerade läsningar

Läsning från den lilla temporära tabellen använder bara buffertcachen, som finns i minnet. Kör bara frågedelen många gånger och se hur consistent gets from cache (minne) ökar medan physical reads cache (disk) förbli densamma.

select name, value
from v$sysstat
where name in ('db block gets from cache', 'consistent gets from cache', 
'physical reads cache');

Optimerade skrivningar

Helst skulle det inte finnas någon fysisk I/O, särskilt eftersom den temporära tabellen är ON COMMIT DELETE ROWS . Och det låter som att nästa version av Oracle kan introducera en sådan mekanism. Men det spelar inte så stor roll i det här fallet, disk I/O verkar inte sakta ner.

Kör laddningssteget flera gånger och kör sedan select * from v$active_session_history order by sample_time desc; . Det mesta av I/O är BACKGROUND , vilket betyder att ingenting väntar på den. Jag antar att den tillfälliga tabellens interna logik bara är en kopia av vanliga DML-mekanismer. I allmänhet kan ny tabelldata måste skrivas till disken, om den är committerad. Oracle kan börja arbeta med det, till exempel genom att flytta data från loggbufferten till disken, men det är ingen brådska förrän det finns en faktisk COMMIT .

Var tar PL/SQL-tiden vägen?

Jag har ingen aning. Finns det flera kontextväxlar, eller en enda konvertering mellan SQL- och PL/SQL-motorerna? Såvitt jag vet visar ingen av de tillgängliga mätvärdena tiden spenderas på att växla mellan SQL och PL/SQL.

Vi kanske aldrig vet exakt varför PL/SQL-kod är långsammare. Jag oroar mig inte för mycket. Det allmänna svaret är att den stora majoriteten av databasarbetet måste göras i SQL ändå. Det skulle vara mycket vettigt om Oracle ägnade mer tid åt att optimera kärnan i sin databas, SQL, än tilläggsspråket PL/SQL.

Ytterligare anmärkningar

För prestandatestning kan det vara bra att ta bort connect by logik i ett separat steg. Att SQL är ett bra knep för att ladda data, men det kan vara väldigt långsamt och resurskrävande. Det är mer realistiskt att ladda en exempeltabell en gång med det tricket och sedan infoga från den tabellen.

Jag försökte använda den nya Oracle 12c-funktionen, temporär ångra, och den nya 18c-funktionen, privata temporära tabeller. Ingen av dem förbättrade prestandan jämfört med vanliga temporära tabeller.

Jag skulle inte satsa på det, men jag kan se ett sätt att resultaten helt skulle förändras när data blir större. Loggbufferten och buffertcachen kan bara bli så stor. Och så småningom kan den bakgrunds-I/O lägga till och överväldiga vissa processer, vilket gör BACKGROUND vänta in i en FOREGROUND vänta. Å andra sidan finns det bara så mycket PGA-minne för PL/SQL-lösningen, och sedan kraschar saker.

Slutligen bekräftar detta delvis min skepsis mot "in-memory-databaser". Cachning är inget nytt, databaser har gjort det i decennier.



  1. Hur man går med två tabeller i MySQL

  2. MySQL-kommandon:Fuskblad med vanliga MySQL-frågor

  3. Infogar rader i en tabell med endast en IDENTITY-kolumn

  4. Fyra vanliga myter om molnteknik