sql >> Database >  >> RDS >> Oracle

Prestatieoverwegingen voor tijdelijke gegevens in Oracle

Tijdelijke tabellen zijn in feite hetzelfde als in-memory tabellen dankzij caching en asynchrone I/O, en de tijdelijke tabeloplossing vereist geen overhead voor het converteren tussen SQL en PL/SQL.

De resultaten bevestigen

Als we de twee versies vergelijken met RunStats, ziet de tijdelijke tabelversie er uit veel slechter. Al die rommel voor de tijdelijke tabelversie in Run1 en slechts een beetje extra geheugen voor de PL/SQL-versie in Run2. In eerste instantie lijkt het erop dat PL/SQL de duidelijke winnaar zou moeten zijn.

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

Maar aan het eind van de dag is alleen de tijd van de wandklok van belang. Zowel het laden als het opvragen verloopt veel sneller met tijdelijke tabellen.

De PL/SQL-versie kan worden verbeterd door de BULK COLLECT te vervangen met cast(collect(test_o(MOD(a, 10), '' || MOD(a, 12))) as test_t) INTO t . Maar het is nog steeds aanzienlijk langzamer dan de tijdelijke tabelversie.

Geoptimaliseerde leesbewerkingen

Lezen uit de kleine tijdelijke tabel gebruikt alleen de buffercache, die zich in het geheugen bevindt. Voer alleen het querygedeelte vaak uit en kijk hoe de consistent gets from cache komt (geheugen) toenemen terwijl de physical reads cache (schijf) hetzelfde blijven.

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

Geoptimaliseerde schrijfbewerkingen

Idealiter zou er geen fysieke I/O zijn, vooral omdat de tijdelijke tabel ON COMMIT DELETE ROWS is . En het klinkt alsof de volgende versie van Oracle een dergelijk mechanisme zou kunnen introduceren. Maar in dit geval maakt het niet veel uit, de schijf-I/O lijkt de dingen niet te vertragen.

Voer de laadstap meerdere keren uit en voer vervolgens select * from v$active_session_history order by sample_time desc; . Het grootste deel van de I/O is BACKGROUND , wat betekent dat er niets op wacht. Ik neem aan dat de interne logica van de tijdelijke tabel slechts een kopie is van reguliere DML-mechanismen. Over het algemeen kunnen nieuwe tabelgegevens mogelijk moeten naar schijf worden geschreven, als het is vastgelegd. Oracle kan eraan gaan werken, bijvoorbeeld door gegevens van de logbuffer naar schijf te verplaatsen, maar er is geen haast totdat er een daadwerkelijke COMMIT is .

Waar gaat de PL/SQL-tijd naartoe?

Ik heb geen idee. Zijn er meerdere context-switches, of een enkele conversie tussen de SQL- en PL/SQL-engines? Voor zover ik weet, geeft geen van de beschikbare statistieken de tijd . weer besteed aan het schakelen tussen SQL en PL/SQL.

We zullen misschien nooit precies weten waarom PL/SQL-code langzamer is. Ik maak me er niet al te veel zorgen over. Het algemene antwoord is dat het overgrote deel van het databasewerk sowieso in SQL moet worden gedaan. Het zou heel logisch zijn als Oracle meer tijd zou besteden aan het optimaliseren van de kern van hun database, SQL, dan aan de add-on-taal PL/SQL.

Aanvullende opmerkingen

Voor prestatietests kan het handig zijn om de connect by . te verwijderen logica in een aparte stap. Die SQL is een geweldige truc voor het laden van gegevens, maar het kan erg traag en arbeidsintensief zijn. Het is realistischer om een ​​voorbeeldtabel één keer met die truc te laden en vervolgens vanuit die tabel in te voegen.

Ik heb geprobeerd de nieuwe Oracle 12c-functie, tijdelijk ongedaan maken, en de nieuwe 18c-functie, tijdelijke privétabellen te gebruiken. Geen van beide verbeterde de prestaties ten opzichte van gewone tijdelijke tafels.

Ik zou er niet op wedden, maar ik zie een manier waarop de resultaten volledig zouden veranderen naarmate de gegevens groter worden. De logbuffer en de buffercache kunnen alleen zo groot worden. En uiteindelijk zou die achtergrond-I/O kunnen oplopen en sommige processen overweldigen, waardoor de BACKGROUND wacht in een FOREGROUND wacht. Aan de andere kant is er maar zoveel PGA-geheugen voor de PL/SQL-oplossing, en dan crasht het.

Ten slotte bevestigt dit gedeeltelijk mijn scepsis over "in-memory databases". Caching is niets nieuws, databases doen het al tientallen jaren.



  1. Een login.sql-bestand maken voor SQLcl

  2. “PostgreSQL 9.0 High Performance” boek is uit

  3. Hoe de volgspaties na de maandnaam in Oracle te verwijderen

  4. Beslis tussen controle op basis van agenten of controle zonder agenten