So überprüfen Sie die Oracle-Datenbank auf lange laufende Abfragen


98

Meine Anwendung, die eine Oracle-Datenbank verwendet, ist langsam oder scheint vollständig gestoppt zu sein.

Wie kann ich herausfinden, welche Abfragen am teuersten sind, damit ich weitere Nachforschungen anstellen kann?

Antworten:


134

Dieser zeigt SQL, das derzeit "AKTIV" ist: -

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 Schlösser. Manchmal geht es langsam voran, aber es liegt daran, dass es blockiert ist und auf ein Schloss wartet:

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 gut geeignet, um lange Vorgänge zu finden (z. B. vollständige Tabellenscans). Wenn es sich um viele kurze Operationen handelt, 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
/

1
Gibt es eine Möglichkeit, solche Abfragen sicher zu beenden, wenn sie länger als x Minuten ausgeführt werden? Vielen Dank für die Antwort aber @UmberFerrule
TommyT

2
@TommyT Sie können alter system kill sessionwie hier beschrieben verwenden: docs.oracle.com/cd/B28359_01/server.111/b28310/…
WW.

37

Versuchen Sie dies, es werden Abfragen angezeigt, die derzeit länger als 60 Sekunden ausgeführt werden. Beachten Sie, dass pro laufender Abfrage mehrere Zeilen gedruckt werden, wenn SQL mehrere Zeilen enthält. Schauen Sie sich 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

Ich führe diese Abfrage aus und es sagt mir, dass die Anweisung ungültig ist

Es ist gültig. Ich habe es getestet. Mit welchem ​​Tool fragen Sie ab? Es könnte mit dem # -Zeichen verwechselt werden. Versuchen Sie, den Anfang und das Ende folgendermaßen zu ändern: "Wählen Sie * aus ... Bestellung nach Sid, q.piece"
Carlos A. Ibarra

2
Außerdem müssen Sie dies mit einem privilegierten Konto ausführen, das Zugriff auf v $ session, v $ sqltext_with_newlines
WW hat.

Dies funktioniert, gibt aber den SQL-Text der Abfrage sehr seltsam formatiert zurück.
Bernhard Döbler

7

v $ session_longops

Wenn Sie nach sofar! = Totalwork suchen, werden Sie diejenigen sehen, die noch nicht abgeschlossen sind, aber die Einträge werden nicht entfernt, wenn der Vorgang abgeschlossen ist, sodass Sie dort auch viel Verlauf sehen können.


Guter Hinweis. Auch in Einzelheiten diskutiert hier .
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

Sie können einen AWR-Bericht (Automatic Workload Repository) aus der Datenbank generieren.

Führen Sie die SQL * Plus-Befehlszeile aus:

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

Lesen Sie das Dokument zum Erstellen und Verstehen eines AWR-Berichts. Es bietet einen vollständigen Überblick über die Datenbankleistung und Ressourcenprobleme. Sobald wir mit dem AWR-Bericht vertraut sind, ist es hilfreich, Top SQL zu finden, das Ressourcen verbraucht.

Außerdem können wir in der 12C EM Express-Benutzeroberfläche einen AWR generieren.


0

Mit der folgenden Abfrage können Sie die Details zu lang laufenden Abfragen wie% abgeschlossen und verbleibende Zeit überprüfen:

 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;

Die vollständige Liste der Schritte zur Fehlerbehebung finden Sie hier: Fehlerbehebung bei Sitzungen mit langer Laufzeit


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;
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.