Come controllare il database Oracle per query a lunga esecuzione


99

La mia applicazione, che utilizza un database Oracle, sta rallentando o sembra essersi arrestata completamente.

Come posso scoprire quali query sono più costose, in modo da poter indagare ulteriormente?

Risposte:


134

Questo mostra l'SQL che è attualmente "ATTIVO": -

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
/

Questo mostra le serrature. A volte le cose vanno lentamente, ma è perché è bloccato in attesa di un blocco:

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
/

Questo è utile per trovare operazioni lunghe (ad esempio scansioni complete di tabelle). Se è a causa di molte operazioni brevi, non verrà visualizzato nulla.

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
C'è un modo per terminare in modo sicuro tali query se vengono eseguite per più di x minuti. Grazie per la risposta però @UmberFerrule
TommyT

2
@TommyT È possibile utilizzare alter system kill sessioncome descritto qui: docs.oracle.com/cd/B28359_01/server.111/b28310/…
WW.

37

Prova questo, ti darà le query attualmente in esecuzione per più di 60 secondi. Si noti che stampa più righe per query in esecuzione se l'SQL ha più righe. Guarda il sid, serial # per vedere cosa appartiene insieme.

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

Eseguo questa query e mi dice che non è una dichiarazione non valida

È valido. L'ho provato. Quale strumento stai usando per interrogare? Potrebbe essere confuso con il segno #. Prova a cambiare l'inizio e la fine in questo modo: "seleziona * da ... ordina per sid, q.piece"
Carlos A. Ibarra

2
Inoltre, dovrai eseguirlo con un account privato che abbia accesso a v $ session, v $ sqltext_with_newlines
WW.

Funziona ma restituisce il testo SQL della query con un formato molto strano.
Bernhard Döbler

7

v $ session_longops

Se cerchi sofar! = Totalwork vedrai quelli che non sono stati completati, ma le voci non vengono rimosse al termine dell'operazione, quindi puoi vedere anche molta cronologia.


Buon suggerimento. Discusso anche in dettaglio qui .
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

È possibile generare un report AWR (repository automatico del carico di lavoro) dal database.

Esegui dalla riga di comando SQL * Plus:

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

Leggi il documento relativo a come generare e comprendere un rapporto AWR. Fornirà una visione completa delle prestazioni del database e dei problemi relativi alle risorse. Una volta acquisita familiarità con il rapporto AWR, sarà utile trovare Top SQL che consuma risorse.

Inoltre, nell'interfaccia utente di 12C EM Express possiamo generare un AWR.


0

Puoi controllare i dettagli delle query di lunga durata come% completata e tempo rimanente utilizzando la query seguente:

 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;

Per l'elenco completo dei passaggi per la risoluzione dei problemi, puoi controllare qui: Risoluzione dei problemi di sessioni di lunga durata


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;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.