Oracle
 sql >> база данни >  >> RDS >> Oracle

Съображения за производителност за временни данни в Oracle

Временните таблици на практика са същите като таблиците в паметта благодарение на кеширането и асинхронния I/O, а решението за временна таблица не изисква никакви допълнителни разходи за преобразуване между SQL и PL/SQL.

Потвърждаване на резултатите

Сравнявайки двете версии с RunStats, версията на временната таблица изглежда много по-зле. Всички тези боклуци за версията за временна таблица в Run1 и само малко допълнителна памет за версията PL/SQL в Run2. Отначало изглежда, че PL/SQL трябва да бъде ясният победител.

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

Но в края на деня само времето на стенния часовник има значение. И стъпките за зареждане и заявка се изпълняват много по-бързо с временни таблици.

Версията PL/SQL може да бъде подобрена чрез замяна на BULK COLLECT с cast(collect(test_o(MOD(a, 10), '' || MOD(a, 12))) as test_t) INTO t . Но все още е значително по-бавна от версията за временна таблица.

Оптимизирано четене

Четенето от малката временна таблица използва само буферния кеш, който е в паметта. Изпълнете само частта със заявката много пъти и наблюдавайте как consistent gets from cache (паметта) се увеличава, докато physical reads cache (диск) остава същият.

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

Оптимизирани записи

В идеалния случай няма да има физически I/O, особено след като временната таблица е ON COMMIT DELETE ROWS . И изглежда, че следващата версия на Oracle може да въведе такъв механизъм. Но това няма голямо значение в този случай, дисковият I/O изглежда не забавя нещата.

Изпълнете стъпката за зареждане няколко пъти и след това изпълнете select * from v$active_session_history order by sample_time desc; . По-голямата част от I/O е BACKGROUND , което означава, че нищо не го чака. Предполагам, че вътрешната логика на временната таблица е просто копие на обикновени DML механизми. По принцип нови данни в таблицата могат трябва да бъдат записани на диск, ако е ангажиран. Oracle може да започне да работи по него, например чрез преместване на данни от буфера на журнала на диск, но няма бързане, докато не се извърши действително COMMIT .

Къде отива времето за PL/SQL?

Аз нямам представа. Има ли множество превключватели на контекста или едно преобразуване между SQL и PL/SQL двигателите? Доколкото знам нито един от наличните показатели не показва времето изразходвани за превключване между SQL и PL/SQL.

Може никога да не разберем точно защо PL/SQL кодът е по-бавен. Не се тревожа много за това. Общият отговор е, че по-голямата част от работата с базата данни трябва да се извършва в SQL така или иначе. Би имало много смисъл, ако Oracle отдели повече време за оптимизиране на ядрото на тяхната база данни, SQL, отколкото езика на добавките, PL/SQL.

Допълнителни бележки

За тестване на производителността може да бъде полезно да премахнете connect by логиката в отделна стъпка. Този SQL е страхотен трик за зареждане на данни, но може да бъде много бавен и ресурсоемък. По-реалистично е да заредите примерна таблица веднъж с този трик и след това да вмъкнете от тази таблица.

Опитах да използвам новата функция на Oracle 12c, временно отмяна, и новата функция 18c, частни временни таблици. Нито едното не подобри производителността спрямо обикновените временни таблици.

Не бих заложил на това, но виждам начин резултатите да се променят напълно с увеличаването на данните. Буферът на журнала и кешът на буфера могат да станат толкова големи. И в крайна сметка този фонов вход/изход може да се добави и да затрупа някои процеси, превръщайки BACKGROUND изчакайте в FOREGROUND изчакайте. От друга страна, има само толкова много PGA памет за PL/SQL решението и тогава нещата се сриват.

И накрая, това отчасти потвърждава моя скептицизъм към „базите данни в паметта“. Кеширането не е нищо ново, базите данни го правят от десетилетия.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Итерацията на ResultSet с помощта на JDBC за Oracle отнема много време около 16 секунди?

  2. Oracle След изтриване на тригер... Как да избегнем мутираща таблица (ORA-04091)?

  3. Конфигуриране на репликация на хетерогенна база данни – SQL Server към Oracle

  4. разлика между план за обяснение и план за изпълнение

  5. Параметри за свързване към Oracle Dynamic SQL