oracle awr - ghdrako/doc_snipets GitHub Wiki
AWR (Automatic Workload Repository)
AWR zbiera dane o obciążeniu systemu i zapytaniach SQL co określony interwał (domyślnie 1 godzina) i przechowuje je w historycznych migawkach (snapshots). Możemy te dane wykorzystać do:
- Identyfikacji wolnych zapytań.
- Analizy zużycia zasobów (CPU, I/O, pamięć).
- Optymalizacji indeksów i statystyk.
- Wykrywania problemów wydajnościowych w bazie danych.
Tworzenie raportu AWR
Aby wygenerować raport AWR, możemy użyć SQL*Plus lub Enterprise Managera.
Metoda 1: SQL*Plus
SELECT snap_id, begin_interval_time, end_interval_time
FROM dba_hist_snapshot
ORDER BY snap_id DESC;
Po uzyskaniu identyfikatorów migawki (snap_id), generujemy raport:
@$ORACLE_HOME/rdbms/admin/awrrpt.sql
Następnie podajemy:
- Format raportu (HTML/TEXT).
- Zakres czasu (początkowa i końcowa migawka).
- Nazwę pliku wynikowego.
Metoda 2: Enterprise Manager (OEM)
- Logujemy się do Oracle Enterprise Manager.
- Przechodzimy do zakładki Performance → AWR.
- Wybieramy zakres czasu i generujemy raport.
Analiza raportu AWR pod kątem zapytań SQL
-
A. Top 10 SQL by Elapsed Time - Pokazuje najwolniejsze zapytania pod względem czasu wykonania.
- Wartość Elapsed Time (s) wskazuje całkowity czas wykonania SQL.
- Executions oznacza liczbę wywołań
-
B. Top 10 SQL by CPU Time - pokazuje zapytania, które zużywają najwięcej CPU.
- Jeśli jedno zapytanie zajmuje 80% CPU, należy sprawdzić jego plan wykonania i indeksy.
- Możliwe optymalizacje: indeksy, restrukturyzacja zapytania, zmiana algorytmów sortowania.
-
C. Top 10 SQL by I/O Wait Time -nPokazuje zapytania z największymi opóźnieniami na operacjach I/O.
- Jeśli zapytanie często wykonuje operacje FULL TABLE SCAN, warto dodać indeksy.
- Jeśli zapytanie często pobiera duże ilości danych, warto zastosować partycjonowanie tabel.
-
D. SQL Ordered by Buffer Gets - Pokazuje zapytania zużywające najwięcej operacji odczytu z pamięci (buffer cache).
- Jeśli zapytanie często pobiera te same dane, można zastosować caching (Materialized Views, Result Cache).
- Jeśli wartości są odczytywane w sposób nieefektywny, warto sprawdzić statystyki tabel i indeksów.
awr_report.sql
-- Get AWR reports: last day and diffs for 2 dayes
set serveroutput on
alter session set nls_date_format='YYYYMMDD';
column day_before new_value day_before noprint
select to_char((to_date('&1')-1)) as day_before from dual;
column db_id new_value db_id noprint
column inst_id new_value inst_id noprint
column prev_min_id new_value prev_min_id noprint
column prev_max_id new_value prev_max_id noprint
select
min(instance_number) as inst_id,
min(dbid) as db_id,
min(snap_id) as prev_min_id,
max(snap_id) as prev_max_id
from sys.wrm$_snapshot where trunc(end_interval_time)=to_date('&day_before');
column cur_min_id new_value cur_min_id noprint
column cur_max_id new_value cur_max_id noprint
select
min(snap_id) as cur_min_id,
max(snap_id) as cur_max_id
from sys.wrm$_snapshot where trunc(end_interval_time)=to_date('&1');
spool tmp_awr.sql
set linesize 300
set echo off
set term off
set heading off
set feedback off
set verify off
exec dbms_output.put_line('set echo off');
exec dbms_output.put_line('set term off');
exec dbms_output.put_line('set heading off');
exec dbms_output.put_line('set feedback off');
exec dbms_output.put_line('set verify off');
exec dbms_output.put_line('set linesize 1500');
exec dbms_output.put_line('set termout on');
exec dbms_output.put_line('spool dip_&1..html');
exec dbms_output.put_line('select output from table(DBMS_WORKLOAD_REPOSITORY.awr_report_html(&db_id, &inst_id, &cur_min_id, &cur_max_id));');
exec dbms_output.put_line('spool off');
exec dbms_output.put_line('spool dip_&1._&day_before..html');
exec dbms_output.put_line('select output from table(DBMS_WORKLOAD_REPOSITORY.awr_diff_report_html(&db_id, &inst_id, &cur_min_id, &cur_max_id, &db_id, &inst_id, &prev_min_id, &prev_max_id));');
exec dbms_output.put_line('spool off');
exec dbms_output.put_line('set heading on');
exec dbms_output.put_line('set verify on');
exec dbms_output.put_line('set term on');
exec dbms_output.put_line('set feedback on');
spool off
@tmp_awr.sql
select * from (
select
--'OPERTEST' baza,
--SNAP.END_INTERVAL_TIME,
---STAT.SNAP_ID,
TO_CHAR(SNAP.END_INTERVAL_TIME,'YYYY-MM-DD HH24:MI:SS') as END_SNAPTIME, PARSING_SCHEMA_NAME
---, STAT.MODULE
,TXT.SQL_ID, PLAN_HASH_VALUE,
--ELAPSED_TIME_DELTA/1000/1000 as ELAPSED_SEC,
trunc((ELAPSED_TIME_DELTA/EXECUTIONS_DELTA)/1000/1000,4) as ELAPSED_SEC_per_exec,
--executions_total,
STAT.EXECUTIONS_DELTA,
---rows_processed_total,
CASE WHEN rows_processed_total = 0 THEN trunc(rows_processed_total)
WHEN rows_processed_total > 0 THEN trunc(rows_processed_total/executions_total)
ELSE rows_processed_total
END AS zwr_wierszy,
--substr(sql_text,0,20),
SQL_TEXT
from
dba_hist_sqlstat stat,
dba_hist_sqltext txt
,dba_hist_snapshot snap
where
stat.sql_id=txt.sql_id
and stat.snap_id=snap.snap_id
and SNAP.END_INTERVAL_TIME > sysdate - 90
and EXECUTIONS_DELTA > 0
--order by zwr_wierszy desc
order by 1
)
where
sql_id='cuf4u8q0dp6qn';
Zapytanie pobiera historyczne statystyki dotyczące konkretnego zapytania SQL (identyfikowanego przez SQL_ID) z bazy Oracle, wykorzystując widoki AWR: DBA_HIST_SQLSTAT, DBA_HIST_SQLTEXT i DBA_HIST_SNAPSHOT. Oblicza średni czas wykonania pojedynczego wywołania (ELAPSED_SEC_per_exec) oraz średnią liczbę zwracanych wierszy na wywołanie (zwr_wierszy), a następnie prezentuje pełny tekst SQL wraz z wartością PLAN_HASH_VALUE i czasem wykonania snapshotu dla ostatnich 90 dni. Dzięki temu można analizować wydajność danego SQL-a w przekroju czasowym oraz porównywać plany wykonania.
- end_interval_time odpowiada za czas zakończenia snapshotu, do którego odnoszą się statystyki Dokumentacja Oracle
parsing_schema_name
wskazuje schemat, w którym zapytanie zostało pierwotnie parsowane Dokumentacja Oracleelapsed_time_delta
iexecutions_delta
to przyrosty łącznego czasu wykonania i liczby wykonań w ramach danego snapshotu Dokumentacja Oracle- Wyrażenie
(elapsed_time_delta / executions_delta) / 1e6
zamienia mikrosekundy na sekundy i oblicza średni czas na wykonanie jednego wywołania GitHub rows_processed_total
iexecutions_total
służą do wyliczenia średniej liczby zwróconych wierszy na jedno wywołanie; w przypadku braku zwrotów wynik zwraca zero Carlos Sierra's Tools and Tipssql_text
pochodzi z widokuDBA_HIST_SQLTEXT
i zawiera pełny tekst analizowanego SQL-a Dokumentacja Oraclesnap.end_interval_time > SYSDATE - 90
ogranicza dane do ostatnich 90 dni Dokumentacja Oracleexecutions_delta > 0
wyklucza snapshoty, w których zapytanie nie było wykonywaneDokumentacja Oracle- Ostateczne
WHERE sql_id = '...'
filtruje wynik do interesującego nas konkretnego zapytania. ORDER BY 1
sortuje wynik rosnąco według czasu snapshotu.