sql >> Database teknologi >  >> RDS >> Oracle

Ydelsesovervejelser for midlertidige data i Oracle

Midlertidige tabeller er reelt de samme som tabeller i hukommelsen takket være caching og asynkron I/O, og den midlertidige tabelløsning kræver ingen overhead til konvertering mellem SQL og PL/SQL.

Bekræftelse af resultaterne

Sammenligner man de to versioner med RunStats, ser den midlertidige tabelversion ud meget værre. Alt det skrammel til den midlertidige tabelversion i Run1, og kun lidt ekstra hukommelse til PL/SQL-versionen i Run2. Umiddelbart ser det ud til, at PL/SQL burde være den klare vinder.

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 slutningen af ​​dagen er det kun væguret, der betyder noget. Både indlæsnings- og forespørgselstrinene kører meget hurtigere med midlertidige tabeller.

PL/SQL-versionen kan forbedres ved at erstatte BULK COLLECT med cast(collect(test_o(MOD(a, 10), '' || MOD(a, 12))) as test_t) INTO t . Men den er stadig betydeligt langsommere end den midlertidige tabelversion.

Optimerede læsninger

Læsning fra den lille midlertidige tabel bruger kun buffercachen, som er i hukommelsen. Kør kun forespørgselsdelen mange gange, og se, hvordan consistent gets from cache (hukommelse) øges, mens physical reads cache (disk) forbliv den samme.

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

Optimeret skrivning

Ideelt set ville der ikke være nogen fysisk I/O, især da den midlertidige tabel er ON COMMIT DELETE ROWS . Og det lyder som om, at den næste version af Oracle måske introducerer en sådan mekanisme. Men det betyder ikke meget i dette tilfælde, disk I/O ser ikke ud til at bremse tingene.

Kør indlæsningstrinnet flere gange, og kør derefter select * from v$active_session_history order by sample_time desc; . Det meste af I/O er BACKGROUND , hvilket betyder, at intet venter på den. Jeg antager, at den midlertidige tabel interne logik kun er en kopi af almindelige DML-mekanismer. Generelt kan nye tabeldata skal skrives til disk, hvis det er begået. Oracle kan begynde at arbejde på det, for eksempel ved at flytte data fra logbufferen til disken, men der er ingen hast, før der er en faktisk COMMIT .

Hvor bliver PL/SQL-tiden af?

Jeg har ingen anelse. Er der flere kontekstskift, eller en enkelt konvertering mellem SQL- og PL/SQL-motorerne? Så vidt jeg ved, viser ingen af ​​de tilgængelige metrics tiden brugt på at skifte mellem SQL og PL/SQL.

Vi ved måske aldrig præcis, hvorfor PL/SQL-kode er langsommere. Jeg bekymrer mig ikke for meget om det. Det generelle svar er, at langt størstedelen af ​​databasearbejdet skal udføres i SQL alligevel. Det ville give meget mening, hvis Oracle brugte mere tid på at optimere kernen af ​​deres database, SQL, end tilføjelsessproget PL/SQL.

Yderligere bemærkninger

Til præstationstestning kan det være nyttigt at fjerne connect by logik ind i et separat trin. Den SQL er et godt trick til at indlæse data, men det kan være meget langsomt og ressourcekrævende. Det er mere realistisk at indlæse en prøvetabel én gang med det trick og derefter indsætte fra den tabel.

Jeg prøvede at bruge den nye Oracle 12c-funktion, midlertidig fortryd, og den nye 18c-funktion, private midlertidige borde. Ingen af ​​dem forbedrede ydeevnen i forhold til almindelige midlertidige tabeller.

Jeg ville ikke satse på det, men jeg kan se en måde, hvorpå resultaterne helt vil ændre sig, efterhånden som dataene bliver større. Logbufferen og buffercachen kan kun blive så stor. Og i sidste ende kunne den baggrunds-I/O tilføje op og overvælde nogle processer og vende BACKGROUND vent ind i en FOREGROUND vente. På den anden side er der kun så meget PGA-hukommelse til PL/SQL-løsningen, og så går tingene i stykker.

Endelig bekræfter dette delvist min skepsis over for "in-memory databaser". Caching er ikke noget nyt, databaser har gjort det i årtier.



  1. selectArgs i SQLiteQueryBuilder virker ikke med heltalsværdier i kolonner

  2. Sådan uploades billeder til MySQL-databasen ved hjælp af PHP-kode

  3. MySQL ukendt kolonne i ON-klausul

  4. Hvorfor har en oracle plsql varchar2-variabel brug for en størrelse, men en parameter ikke?