Como descrito no último artigo (link AQUI), a Time Model é um conjunto de estatísticas que descrevem quais itens da DB Time está sendo gasto do banco de dados. Podemos ver suas informações nas views V$SYS_TIME_MODEL e V$SESS_TIME_MODEL. Os dados dessas views são acumulados desde o startup da instância (em microsegundos), em uma estrutura hierárquica (que tem a DB Time no topo). Como benefícios do seu uso, temos uma visão geral do workload do ambiente. Por exemplo: caso a porcentagem de DB Waits seja maior que 50% da DB Time, podemos ter uma indicação de baixa performance. Obviamente, esse valor em % não é definido assim, pois isso pode variar de ambiente para ambiente. Outro benefício é comparar esses números após uma manutenção, como aumento de memória no servidor, para saber se a carga no banco ficou melhor ou pior. Por último, caso seja identificado um componente com alta porcentagem, pode ser um gargalo de performance no ambiente, permitindo assim a nossa investigação.
Segue abaixo a hierarquia citada, separada em 2 grupos: DB Time e Background Elapsed Time. Este segundo grupo não é contemplado na DB Time, pois ela considera apenas os processos Foreground. Mas ele é considerado na Time Model por uma razão: processos RMAN, pois os mesmos consomem bastante recurso:
Com a consulta abaixo, podemos verificar os dados da Time Model, já convertidos em Segundos. Em suma, a DB Time está em 36 segundos, dos quais 3 segundos foram investidos na DB CPU. Baseado nisso, podemos considerar que o tempo do banco aguardando recursos (DB Waits) foi de 33 segundos:
COL STAT_NAME FORMAT A43
SELECT STAT_NAME, TO_CHAR(VALUE,'999,999,999,999') TIME_MICRO_S
FROM V$SYS_TIME_MODEL
WHERE VALUE <>0 AND STAT_NAME NOT IN ('background elapsed time', 'background cpu time')
ORDER BY VALUE DESC
FETCH FIRST 7 ROWS ONLY;
[oracle@oel7 ~]$ sqlplus / as sysdba
SQL*Plus: Release 19.0.0.0.0 - Production on Tue Sep 7 19:38:44 2021
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle. All rights reserved.
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0
SQL> COL STAT_NAME FORMAT A43
SQL> SELECT STAT_NAME, TO_CHAR(VALUE/1000000,'999,999') TIME_S
FROM V$SYS_TIME_MODEL
WHERE VALUE <>0 AND STAT_NAME NOT IN ('background elapsed time',
'background cpu time')
ORDER BY VALUE DESC
FETCH FIRST 7 ROWS ONLY; 2 3 4 5 6
STAT_NAME TIME_S
------------------------------------------- --------
DB time 36
sql execute elapsed time 22
parse time elapsed 7
hard parse elapsed time 7
DB CPU 3
PL/SQL compilation elapsed time 1
connection management call elapsed time 1
7 rows selected.
Já a consulta abaixo nos reporta os dados da V$SESS_TIME_MODEL, que nos permite identicar os processos que estão consumindo mais DB Time:
col SID format 999999
col USERNAME format a10
col DBTIME format 9999999999999
col WAITTIME format 9999999999999
col WAITPCT format 99999.99
col ONCPUPCT format 99999.99
SELECT M.SID, S.USERNAME
,VALUE DBTIME
,WAITTIME WAITTIME
,ROUND((WAITTIME/VALUE)*100,2) WAITPCT
,ROUND(((VALUE-WAITTIME)/VALUE)*100,2) ONCPU_PCT
FROM(SELECT SID, STAT_ID, STAT_NAME ,VALUE
,VALUE - (LEAD(VALUE,1) OVER(PARTITION BY SID ORDER BY SID,STAT_NAME DESC)) WAITTIME
FROM V$SESS_TIME_MODEL
WHERE STAT_NAME IN ('DB time','DB CPU')) M,
V$SESSION S
WHERE M.SID = S.SID
AND STAT_NAME='DB time' AND WAITTIME>0
ORDER BY WAITPCT DESC;
SQL> col SID format 999999
col USERNAME format a10
col DBTIME format 9999999999999
col WAITTIME format 9999999999999
col WAITPCT format 99999.99
col ONCPUPCT format 99999.99
SELECT M.SID, S.USERNAME
,VALUE DBTIME
,WAITTIME WAITTIME
,ROUND((WAITTIME/VALUE)*100,2) WAITPCT
SQL> ,ROUND(((VALUE-WAITTIME)/VALUE)*100,2) ONCPU_PCT
FROM(SELECT SID, STAT_ID, STAT_NAME ,VALUE
,VALUE - (LEAD(VALUE,1) OVER(PARTITION BY SID ORDER BY SID,STAT_NAME DESC)) WAITTIME
FROM V$SESS_TIME_MODEL
WHERE STAT_NAME IN ('DB time','DB CPU')) M,
V$SESSION S
WHERE M.SID = S.SID
AND STAT_NAME='DB time' AND WAITTIME>0
ORDER BY WAITPCT DESC;
SQL> SQL> SQL> SQL> SQL> 2 3 4 5 6 7 8 9 10 11 12 13
SID USERNAME DBTIME WAITTIME WAITPCT ONCPU_PCT
------- ---------- -------------- -------------- --------- ----------
132 SYSRAC 673089 587010 87.21 12.79
148 SYS 151015 112312 74.37 25.63
Um dos pontos negativos da V$SYS_TIME_MODEL é que a mesma é cumulativa (como já citado), ou seja, considera os dados tantos dos horários de picos, como dos horários de operação “normal”, desde o startup do ambiente. E caso o mesmo seja reiniciado, esses dados são resetados e perdidos. Felizmente, temos uma outra view, com os dados coletados a cada 1 hora (por padrão, mas que pode ser alterado), armazenando um histórico dessas informações. Essa view se chama DBA_HIST_SYS_TIME_MODEL. Com ela, conseguimos até identificar o que ocorreu em um período específico no passado. Segue exemplo:
SQL> SET LIN 200
SQL> SELECT * FROM DBA_HIST_SYS_TIME_MODEL FETCH FIRST 7 ROWS ONLY;
SNAP_ID DBID INSTANCE_NUMBER STAT_ID STAT_NAME VALUE CON_DBID CON_ID
---------- ---------- --------------- ---------- ------------------------------------------- ---------- ---------- ----------
22 548968087 1 3649082374 DB time 40420390 548968087 0
22 548968087 1 2748282437 DB CPU 3253483 548968087 0
22 548968087 1 4157170894 background elapsed time 242290269 548968087 0
22 548968087 1 2451517896 background cpu time 51754547 548968087 0
22 548968087 1 4127043053 sequence load elapsed time 0 548968087 0
22 548968087 1 1431595225 parse time elapsed 9042452 548968087 0
22 548968087 1 372226525 hard parse elapsed time 8765551 548968087 0
7 rows selected.
Obs: Este procedimento foi criado pelo senhor Ahmed Baraka (www.ahmedbaraka.com) e foi apenas reproduzido por mim em um laboratório pessoal para fins de aprendizado.