2009-03-07 6 views
76

Meine Anwendung, die eine Oracle-Datenbank verwendet, wird langsam oder scheinbar vollständig gestoppt.Wie Oracle-Datenbank für lange laufende Abfragen überprüfen?

Wie kann herausfinden, welche Abfragen am teuersten sind, damit ich weiter untersuchen kann?

+10

Ich verstehe wirklich nicht, wie das ist "keine echte Frage" –

+5

Dies ist die nützlichste gefälschte Frage, die ich je gesehen habe :) – FGreg

+4

Dieser Beitrag kommt als # 1 beim googeln "Orakel langsam laufenden Abfragen". Wie wäre es mit der Wiederaufnahme der Frage, um mehr Antworten zu ermöglichen, um aktuell zu bleiben? – andersand

Antwort

26

Probieren Sie dies aus, es gibt Ihnen Abfragen, die derzeit länger als 60 Sekunden dauern. Beachten Sie, dass mehrere Zeilen pro laufender Abfrage gedruckt werden, wenn SQL mehrere Zeilen enthält. Schau dir die Seriennummer an, um zu sehen, was zusammen gehört.

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

Ich führe diese Abfrage und es sagen mir ist ungültig Anweisung –

+0

Es; s gültig. Ich habe es getestet. Mit welchem ​​Tool suchen Sie? Es könnte mit dem Zeichen # verwechselt werden. Versuchen Sie, den Anfang und das Ende wie folgt zu ändern: "select * from ... order by sid, q.piece" –

+2

Sie müssen dies auch mit einem privilegierten Konto ausführen, das Zugriff auf v $ session, v $ sqltext_with_newlines hat –

5

v $ session_longops Wenn Sie sofar aussehen! = Totalwork Sie diejenigen sehen werden, die nicht abgeschlossen haben, aber die Einträge nicht entfernt werden, wenn der Betrieb auch dort abgeschlossen ist, so können Sie eine Menge Geschichte sehen .

+0

Guter Hinweis. Auch im Detail diskutiert [hier] (http://stackoverflow.com/questions/199508). –

105

Dieses zeigt SQL, die derzeit "aktiv": -

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 
/

Dies zeigt Schleusen. Manchmal laufen die Dinge langsam, aber es ist, weil es auf eine Sperre wartet gesperrt ist:

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 
/

Dies ist ein guter für die Suche nach langen Operationen (zum Beispiel vollständiger Tabellenscans). Wenn es wegen vieler kurzer Operationen ist, wird nichts angezeigt.

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

Die dritte Abfrage funktionierte für mich, indem ich auch 'serial #' auswählte. –

+0

Gibt es eine Möglichkeit, solche Abfragen sicher zu beenden, wenn sie länger als x Minuten ausgeführt werden. Danke für die Antwort obwohl @UmberFerrule – TommyT

+0

@TommyT Sie können 'alter system kill session' verwenden, wie hier beschrieben: 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

Sie können AWR (Automatic Workload Repository) Bericht von DB generieren. Run von SQL * Plus-Befehlszeile:

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

Dokument liest damit zusammen, wie AWR Bericht zu generieren & verstehen. Es wird vollständige Sicht der DB-Performance & Ressource Problem geben. Sobald wir mit dem AWR-Bericht vertraut sind, wird es hilfreich sein, Top SQL zu finden, die Ressourcen verbraucht.

In 12C EM Express UI können wir auch AWR generieren.

Verwandte Themen