Como verificar o banco de dados Oracle para consultas de longa duração

98

Meu aplicativo, que usa um banco de dados Oracle, está lento ou parece ter parado completamente.

Como posso descobrir quais consultas são mais caras, para que eu possa investigar mais a fundo?

Peter Mortensen
fonte

Respostas:

134

Este mostra o SQL que está atualmente "ATIVO": -

select S.USERNAME, s.sid, s.osuser, t.sql_id, sql_text
from v$sqltext_with_newlines t,V$SESSION s
where t.address =s.sql_address
and t.hash_value = s.sql_hash_value
and s.status = 'ACTIVE'
and s.username <> 'SYSTEM'
order by s.sid,t.piece
/

Isso mostra bloqueios. Às vezes, as coisas estão lentas, mas é porque ele está bloqueado esperando por um bloqueio:

select
  object_name, 
  object_type, 
  session_id, 
  type,         -- Type or system/user lock
  lmode,        -- lock mode in which session holds lock
  request, 
  block, 
  ctime         -- Time since current mode was granted
from
  v$locked_object, all_objects, v$lock
where
  v$locked_object.object_id = all_objects.object_id AND
  v$lock.id1 = all_objects.object_id AND
  v$lock.sid = v$locked_object.session_id
order by
  session_id, ctime desc, object_name
/

Este é um bom para localizar operações longas (por exemplo, varreduras completas de tabela). Se for por causa de muitas operações curtas, nada aparecerá.

COLUMN percent FORMAT 999.99 

SELECT sid, to_char(start_time,'hh24:mi:ss') stime, 
message,( sofar/totalwork)* 100 percent 
FROM v$session_longops
WHERE sofar/totalwork < 1
/
WW.
fonte
1
Existe uma maneira de eliminar com segurança essas consultas se elas forem executadas por mais de x minutos. Obrigado pela resposta embora @UmberFerrule
TommyT
2
@TommyT Você pode usar alter system kill sessionconforme descrito aqui: docs.oracle.com/cd/B28359_01/server.111/b28310/…
WW.
37

Tente fazer isso, ele apresentará consultas atualmente em execução por mais de 60 segundos. Observe que ele imprime várias linhas por consulta em execução se o SQL tiver várias linhas. Olhe para o sid, número de série para ver o que está junto.

select s.username,s.sid,s.serial#,s.last_call_et/60 mins_running,q.sql_text from v$session s 
join v$sqltext_with_newlines q
on s.sql_address = q.address
 where status='ACTIVE'
and type <>'BACKGROUND'
and last_call_et> 60
order by sid,serial#,q.piece
Carlos A. Ibarra
fonte
executei esta consulta e ela me diz que é uma declaração inválida
É válido. Eu testei. Qual ferramenta você está usando para consultar? Pode estar se confundindo com o sinal #. Tente mudar o início e o fim assim: "selecionar * de ... ordem por sid, q.paço"
Carlos A. Ibarra
2
Além disso, você precisará executá-lo com uma conta privilegiada que tenha acesso a v $ session, v $ sqltext_with_newlines
WW.
Isso funciona, mas retorna o texto SQL da consulta formatado de forma muito estranha.
Bernhard Döbler
7

v $ session_longops

Se você procurar sofar! = Totalwork, verá os que não foram concluídos, mas as entradas não são removidas quando a operação é concluída, portanto, você também pode ver muito histórico lá.

Gary Myers
fonte
Boa dica. Também discutido em detalhes aqui .
dma_k
4
Step 1:Execute the query

column username format 'a10'
column osuser format 'a10'
column module format 'a16'
column program_name format 'a20'
column program format 'a20'
column machine format 'a20'
column action format 'a20'
column sid format '9999'
column serial# format '99999'
column spid format '99999'
set linesize 200
set pagesize 30
select
a.sid,a.serial#,a.username,a.osuser,c.start_time,
b.spid,a.status,a.machine,
a.action,a.module,a.program
from
v$session a, v$process b, v$transaction c,
v$sqlarea s
Where
a.paddr = b.addr
and a.saddr = c.ses_addr
and a.sql_address = s.address (+)
and to_date(c.start_time,'mm/dd/yy hh24:mi:ss') <= sysdate - (15/1440) -- running for 15 minutes
order by c.start_time
/   

Step 2: desc v$session

Step 3:select sid, serial#,SQL_ADDRESS, status,PREV_SQL_ADDR from v$session where sid='xxxx' //(enter the sid value)

Step 4: select sql_text from v$sqltext where address='XXXXXXXX';

Step 5: select piece, sql_text from v$sqltext where address='XXXXXX' order by piece;
mani22487
fonte
1

Você pode gerar um relatório AWR (repositório automático de carga de trabalho) do banco de dados.

Execute a partir da linha de comando SQL * Plus:

SQL> @$ORACLE_HOME/rdbms/admin/awrrpt.sql

Leia o documento relacionado a como gerar e entender um relatório AWR. Ele dará uma visão completa do desempenho do banco de dados e dos problemas de recursos. Assim que estivermos familiarizados com o relatório AWR, será útil encontrar o SQL superior que está consumindo recursos.

Além disso, no 12C EM Express UI, podemos gerar um AWR.

Ramki
fonte
0

Você pode verificar os detalhes das consultas de longa duração, como% concluída e tempo restante, usando a consulta abaixo:

 SELECT SID, SERIAL#, OPNAME, CONTEXT, SOFAR, 
 TOTALWORK,ROUND(SOFAR/TOTALWORK*100,2) "%_COMPLETE" 
 FROM V$SESSION_LONGOPS 
 WHERE OPNAME NOT LIKE '%aggregate%' 
       AND TOTALWORK != 0 
       AND SOFAR <> TOTALWORK;

Para obter a lista completa de etapas de solução de problemas, você pode verificar aqui: Solucionando problemas de sessões de longa duração

Santosh Tiwary
fonte
0
select sq.PARSING_SCHEMA_NAME, sq.LAST_LOAD_TIME, sq.ELAPSED_TIME, sq.ROWS_PROCESSED, ltrim(sq.sql_text), sq.SQL_FULLTEXT
  from v$sql sq, v$session se
 order by sq.ELAPSED_TIME desc, sq.LAST_LOAD_TIME desc;
Akasha
fonte