Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Zagadnienia dotyczące wydajności danych tymczasowych w Oracle

Tabele tymczasowe są w rzeczywistości takie same jak tabele w pamięci dzięki buforowaniu i asynchronicznym we/wy, a rozwiązanie w zakresie tabel tymczasowych nie wymaga żadnych dodatkowych nakładów na konwersję między SQL a PL/SQL.

Potwierdzanie wyników

Porównując obie wersje z RunStats, tymczasowa wersja tabeli wygląda duzo gorszy. Wszystkie te śmieci dla wersji tabeli tymczasowej w Run1 i tylko trochę dodatkowej pamięci dla wersji PL/SQL w Run2. Na początku wydaje się, że PL/SQL powinien być wyraźnym zwycięzcą.

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

Ale pod koniec dnia liczy się tylko czas zegara ściennego. Zarówno ładowanie, jak i wykonywanie zapytań przebiegają znacznie szybciej w przypadku tabel tymczasowych.

Wersję PL/SQL można ulepszyć, zastępując BULK COLLECT z cast(collect(test_o(MOD(a, 10), '' || MOD(a, 12))) as test_t) INTO t . Ale nadal jest znacznie wolniejszy niż wersja tymczasowej tabeli.

Zoptymalizowane odczyty

Odczyt z małej tabeli tymczasowej wykorzystuje jedynie bufor bufora, który znajduje się w pamięci. Uruchom tylko część zapytania wiele razy i obserwuj, jak consistent gets from cache (pamięć) wzrasta, gdy physical reads cache (dysk) pozostanie taki sam.

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

Zoptymalizowane zapisy

Idealnie byłoby, gdyby nie było fizycznych operacji we/wy, zwłaszcza, że ​​tabela tymczasowa to ON COMMIT DELETE ROWS . I wygląda na to, że kolejna wersja Oracle może wprowadzić taki mechanizm. Ale w tym przypadku nie ma to większego znaczenia, dyskowe I/O nie wydaje się spowalniać.

Uruchom krok ładowania wiele razy, a następnie uruchom select * from v$active_session_history order by sample_time desc; . Większość I/O to BACKGROUND , co oznacza, że ​​nic na nią nie czeka. Zakładam, że wewnętrzna logika tabeli tymczasowej jest po prostu kopią zwykłych mechanizmów DML. Ogólnie rzecz biorąc, nowe dane tabeli mogą musi być zapisany na dysku, jeśli jest popełniony. Oracle może zacząć nad tym pracować, na przykład przenosząc dane z bufora dziennika na dysk, ale nie ma pośpiechu, dopóki nie nastąpi faktyczne COMMIT .

Gdzie idzie czas PL/SQL?

Nie mam pojęcia. Czy istnieje wiele przełączników kontekstu lub pojedyncza konwersja między silnikami SQL i PL/SQL? O ile wiem, żaden z dostępnych wskaźników nie pokazuje czasu spędziłem na przełączaniu się między SQL a PL/SQL.

Możemy nigdy nie wiedzieć dokładnie, dlaczego kod PL/SQL jest wolniejszy. Nie przejmuję się tym zbytnio. Ogólna odpowiedź brzmi:zdecydowana większość pracy z bazą danych i tak musi być wykonana w SQL. Byłoby dużo sensu, gdyby Oracle poświęciło więcej czasu na optymalizację rdzenia swojej bazy danych, SQL, niż języka dodatkowego, PL/SQL.

Dodatkowe uwagi

W przypadku testowania wydajności pomocne może być usunięcie connect by logiki w oddzielnym kroku. Ten kod SQL to świetna sztuczka do ładowania danych, ale może być bardzo powolna i wymagająca dużej ilości zasobów. Bardziej realistycznie jest załadować przykładową tabelę raz za pomocą tej sztuczki, a następnie wstawić ją z tej tabeli.

Próbowałem użyć nowej funkcji Oracle 12c, tymczasowego cofania i nowej funkcji 18c, prywatnych tabel tymczasowych. Żaden z nich nie poprawił wydajności w porównaniu ze zwykłymi tabelami tymczasowymi.

Nie stawiałbym na to, ale widzę sposób, w jaki wyniki zmienią się całkowicie, gdy dane będą większe. Bufor dziennika i pamięć podręczna bufora mogą być tylko tak duże. I w końcu to we/wy w tle może sumować się i przytłaczać niektóre procesy, zmieniając BACKGROUND czekać na FOREGROUND czekać. Z drugiej strony jest tylko tyle pamięci PGA dla rozwiązania PL/SQL, a potem wszystko się zawiesza.

W końcu to częściowo potwierdza mój sceptycyzm wobec "baz danych w pamięci". Buforowanie nie jest niczym nowym, bazy danych robią to od dziesięcioleci.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Powolna migracja do chmury

  2. Korzyści z nauki nowych systemów DB

  3. Co to w ogóle jest wersja główna?

  4. Przykład Oracle Bulk Collect przy użyciu obiektu typu kursora typu Rowtype

  5. Wstawianie do tabeli zagnieżdżonej Oracle w Javie