Cómo verificar la base de datos Oracle para consultas de larga ejecución


99

Mi aplicación, que usa una base de datos Oracle, va lenta o parece haberse detenido por completo.

¿Cómo puedo saber qué consultas son más caras para poder investigar más?

Respuestas:


134

Este muestra SQL que actualmente está "ACTIVO": -

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
/

Esto muestra bloqueos. A veces las cosas van lentas, pero es porque está bloqueado esperando un bloqueo:

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
/

Esta es una buena opción para encontrar operaciones largas (por ejemplo, escaneos de tablas completas). Si es debido a muchas operaciones cortas, no aparecerá nada.

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
/

1
¿Hay alguna forma de eliminar de forma segura estas consultas si se ejecutan durante más de x minutos? Aunque gracias por la respuesta @UmberFerrule
TommyT

2
@TommyT Puede usarlo alter system kill sessioncomo se describe aquí: docs.oracle.com/cd/B28359_01/server.111/b28310/…
WW.

37

Pruebe esto, le dará las consultas que se están ejecutando actualmente durante más de 60 segundos. Tenga en cuenta que imprime varias líneas por consulta en ejecución si el SQL tiene varias líneas. Mire el sid, número de serie para ver qué es lo que corresponde.

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

ejecuto esta consulta y me dice que es una declaración inválida

Es válido. Lo probé. ¿Qué herramienta estás usando para realizar consultas? Puede confundirse con el signo #. Intente cambiar el principio y el final así: "seleccionar * de ... ordenar por sid, q.piece"
Carlos A. Ibarra

2
Además, deberá ejecutar esto con una cuenta privilegiada que tenga acceso a v $ session, v $ sqltext_with_newlines
WW.

Esto funciona pero devuelve el texto SQL de la consulta con un formato muy extraño.
Bernhard Döbler

7

v $ session_longops

Si busca sofar! = Totalwork, verá las que no se han completado, pero las entradas no se eliminan cuando se completa la operación, por lo que también puede ver mucho historial allí.


Buen indicio. También se discute en detalle aquí .
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;

1

Puede generar un informe AWR (repositorio automático de carga de trabajo) a partir de la base de datos.

Ejecutar desde la línea de comandos de SQL * Plus:

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

Lea el documento relacionado con cómo generar y comprender un informe de AWR. Le dará una visión completa del rendimiento de la base de datos y los problemas de recursos. Una vez que estemos familiarizados con el informe AWR, será útil encontrar Top SQL que consume recursos.

Además, en la interfaz de usuario de 12C EM Express podemos generar un AWR.


0

Puede verificar los detalles de las consultas de larga duración, como el% completado y el tiempo restante, utilizando la siguiente consulta:

 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 obtener la lista completa de pasos para la solución de problemas, puede consultar aquí: Solución de problemas de sesiones de larga duración


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;
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.