Oracle에서 성능이 저하된 SQL 쿼리를 찾으려면 어떻게 해야 합니까?
Oracle은 공유 SQL 영역에 대한 통계를 유지 관리하며 SQL 문자열당 하나의 행(v$sqlarea)을 포함합니다. 하지만 그 중 어떤 것이 성능이 나쁜지 어떻게 식별할 수 있을까요?
이 SQL 문이 유용한 시작점이라는 것을 알았습니다(원저자의 출처를 밝힐 수 없어서 죄송합니다. 인터넷 어딘가에서 찾았습니다):
SELECT * FROM
(SELECT
sql_fulltext,
sql_id,
elapsed_time,
child_number,
disk_reads,
executions,
first_load_time,
last_load_time
FROM v$sql
ORDER BY elapsed_time DESC)
WHERE ROWNUM < 10
/
이것은 현재 SQL 캐시에 저장되어 있는 상위 SQL 문을 경과된 시간 순으로 찾습니다. 문은 시간이 지남에 따라 캐시에서 사라지므로 정오에 출근할 때 어젯밤의 배치 작업을 진단하려고 시도하는 것은 좋지 않을 수 있습니다.
디스크_읽기 및 실행을 기준으로 순서를 정할 수도 있습니다. 실행 횟수는 일부 불량 애플리케이션이 동일한 SQL 문을 너무 많이 전송하기 때문에 유용합니다. 이 SQL은 바인드 변수를 올바르게 사용한다고 가정합니다.
그런 다음 문의 sql_id
및 child_number
를 가져와서 이 아기에 다음과 같이 공급할 수 있습니다.
SELECT * FROM table(DBMS_XPLAN.DISPLAY_CURSOR('&sql_id', &child));
이렇게 하면 SQL 캐시의 실제 계획과 SQL의 전체 텍스트가 표시됩니다.
이 같은 일이 있는 전체 테이블 검색 디스크입니다 집약형에 찾을 수 있습니다.
SELECT Disk_Reads DiskReads, Executions, SQL_ID, SQL_Text SQLText,
SQL_FullText SQLFullText
FROM
(
SELECT Disk_Reads, Executions, SQL_ID, LTRIM(SQL_Text) SQL_Text,
SQL_FullText, Operation, Options,
Row_Number() OVER
(Partition By sql_text ORDER BY Disk_Reads * Executions DESC)
KeepHighSQL
FROM
(
SELECT Avg(Disk_Reads) OVER (Partition By sql_text) Disk_Reads,
Max(Executions) OVER (Partition By sql_text) Executions,
t.SQL_ID, sql_text, sql_fulltext, p.operation,p.options
FROM v$sql t, v$sql_plan p
WHERE t.hash_value=p.hash_value AND p.operation='TABLE ACCESS'
AND p.options='FULL' AND p.object_owner NOT IN ('SYS','SYSTEM')
AND t.Executions > 1
)
ORDER BY DISK_READS * EXECUTIONS DESC
)
WHERE KeepHighSQL = 1
AND rownum <=5;
당 활동 기간 동안 평균 실행 버퍼 얻을 수 있다면 시행하십시오 인스턴스의:
SELECT username,
buffer_gets,
disk_reads,
executions,
buffer_get_per_exec,
parse_calls,
sorts,
rows_processed,
hit_ratio,
module,
sql_text
-- elapsed_time, cpu_time, user_io_wait_time, ,
FROM (SELECT sql_text,
b.username,
a.disk_reads,
a.buffer_gets,
trunc(a.buffer_gets / a.executions) buffer_get_per_exec,
a.parse_calls,
a.sorts,
a.executions,
a.rows_processed,
100 - ROUND (100 * a.disk_reads / a.buffer_gets, 2) hit_ratio,
module
-- cpu_time, elapsed_time, user_io_wait_time
FROM v$sqlarea a, dba_users b
WHERE a.parsing_user_id = b.user_id
AND b.username NOT IN ('SYS', 'SYSTEM', 'RMAN','SYSMAN')
AND a.buffer_gets > 10000
ORDER BY buffer_get_per_exec DESC)
WHERE ROWNUM <= 20
Oracle 9i 달려 확인할 수 있으며, 이하 버전에 대한 내용, 후에 1 은 [Statspack], [2], [awr] 10g 이상 운영까지도 sql& # 39 위, 이 두 툴과도 너회가 부여하느뇨 srdf/s 및 많은 다른 얘기입니다.
[2]: http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/autostat.htm # PFGRF027
많은 수의 디스크 수행하는 쿼리하지 다음 SQL 문을 되돌려줍니다 판독합니다 (횟수 등을 포함, 사용자와 쿼리하지 실행한):
SELECT t2.username, t1.disk_reads, t1.executions,
t1.disk_reads / DECODE(t1.executions, 0, 1, t1.executions) as exec_ratio,
t1.command_type, t1.sql_text
FROM v$sqlarea t1, dba_users t2
WHERE t1.parsing_user_id = t2.user_id
AND t1.disk_reads > 100000
ORDER BY t1.disk_reads DESC
Sys 로 쿼리하지 실행하십시오 및 디스크 수를 조정하십시오 판독합니다 너희는너희가 따라 수 있다고 생각하는 지나친 (100,000 작동됨 가져다줄래요).
가장 최근 사용한 이 질의에서는 활용할 계획을 실행하기 전에 사용자를 추적할 수 있도록 하는 '그들의' 설명하란말야 명령문입니다.
내가 찾은 이 늙은 Oracle SQL 쿼리를 튜닝함으로써 책 (어떤 난 더 이상 %s/dbase/ext_table. 죄송합니다.), 따라서 있지 않지만, 사과 표시.
검색하는 동안 한 가지 가정(쿼리 실행 시간 6초)으로 작업을 수행하는 다음 쿼리를 얻었습니다.
SELECT username, sql_text, sofar, totalwork, units
FROM v$sql,v$session_longops
WHERE sql_address = 주소 AND sql_hash_value = 해시_값
ORDER BY 주소, 해시값, child_number;
위의 쿼리는 현재 사용자에 대한 세부 정보를 나열할 것입니다.
의견을 환영합니다!!