2009-03-07 5 views
76

La mia applicazione, che utilizza un database Oracle, sta andando lentamente o sembra essersi fermata completamente.Come controllare il database di Oracle per query a esecuzione prolungata?

Come scoprire quali sono le query più costose, quindi posso effettuare ulteriori accertamenti?

+10

Io davvero non capisco come questo non è "una vera domanda" –

+5

Questa è la domanda falso più utile che abbia mai visto :) – FGreg

+4

Questo post si presenta come # 1 quando si cerca su google "oracle slow running query". Che ne dici di riaprire la domanda per consentire a più risposte di rimanere aggiornate? – andersand

risposta

26

Prova questo, ti darà 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, numero di serie 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 
+0

Eseguo questa query e mi dice che l'istruzione non è valida –

+0

È valida. 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" –

+2

Inoltre, devi eseguire questo con un account privilegiato che abbia accesso a v $ session, v $ sqltext_with_newlines –

5

v $ session_longops Se cercate sofar! = Totalwork vedrete quelli che non hanno completato, ma le voci non vengono rimossi quando l'operazione viene completata in modo da poter vedere un sacco di storia anche lì .

+0

Buon suggerimento. Discusso anche nei dettagli [qui] (http://stackoverflow.com/questions/199508). –

105

Questo mostra 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 
/

Questa mostra serrature. A volte le cose stanno andando lentamente, ma è perché è bloccato in attesa di una serratura:

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 è un buon uno per la ricerca di operazioni lunghe (ad esempio le scansioni di tabella completa). Se è a causa di molte brevi operazioni, 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 
/
+0

La terza query ha funzionato per me selezionando 'serial #'. –

+0

C'è un modo per uccidere in modo sicuro tali query se vengono eseguite per più di x minuti. Grazie per la risposta però @UmberFerrule – TommyT

+0

@TommyT È possibile utilizzare 'alter system kill session' come descritto qui: https://docs.oracle.com/cd/B28359_01/server.111/b28310/manproc008.htm#ADMIN11192 –

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; 
0

È possibile generare AWR (Automatic Workload Repository) relazione DB. Run da SQL * Plus riga di comando:

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

Leggi documenti relativi al come generare & capire rapporto AWR. fornirà una visione completa del problema delle prestazioni & delle prestazioni del DB. una volta acquisita familiarità con il rapporto AWR, sarà utile trovare Top SQL che utilizza la risorsa.

In 12C EM express UI anche noi possiamo generare AWR.