bestsource

실행 중인 실제 Oracle SQL 문을 보는 방법

bestsource 2023. 7. 13. 21:00
반응형

실행 중인 실제 Oracle SQL 문을 보는 방법

저는 매주 표준 보고서 세트를 생성하는 맞춤형 사내 애플리케이션을 사용하고 있습니다.저는 애플리케이션의 소스 코드에 액세스할 수 없으며, 모두가 Oracle 데이터베이스 스키마에 사용할 수 있는 문서가 없다고 말합니다. (으악!)

기존 보고서의 변형에 대한 사양을 정의하라는 요청을 받았습니다(예: 추가 필터를 적용하여 데이터 세트를 제한하고 레이아웃을 약간 수정).이것은 원칙적으로 충분히 단순하게 들리지만, 기존 문서가 없으면 어렵습니다.

보고서는 데이터베이스만 조회하고 데이터베이스 값은 실제로 삽입, 삭제 또는 업데이트하지 않으므로 로그에 기록할 내용이 없는 것으로 알고 있습니다(맞습니까?).

제 질문은 다음과 같습니다. 보고서 생성 작업이 계속 실행되는 동안 실행 중인 실제 SQL 문을 확인하는 데 사용할 수 있는 도구나 유틸리티(Oracle 또는 기타)가 있습니까?기존 보고서를 생성하기 위해 실제로 액세스 중인 테이블을 확인할 수 있다면 스키마를 탐색하고 자체 보고서에 사용할 올바른 SQL을 결정하는 데 매우 좋은 출발점이 될 것입니다.

데이터 사전에는 Schema Spy와 같은 많은 도구를 사용할 수 있습니다.

실행 중인 쿼리를 보려면 뷰 sys를 확인합니다.v_$sql 및 sys.v_$sqltext입니다.또한 sys에 액세스할 수 있어야 합니다.all_users

한 가지 주의할 점은 매개 변수를 사용하는 쿼리가 다음과 같은 항목과 함께 한 번 표시된다는 것입니다.

and TABLETYPE=’:b16’

다음과 같이 여러 번 표시되지 않는 다른 항목:

and TABLETYPE=’MT’

이러한 테이블이 작동하는 예로는 상위 20개의 디스크 읽기 호그를 찾기 위한 다음 SQL이 있습니다.WHERE 행 번호 <= 20을 제거하여 이를 변경할 수 있으며 ORDER BY 모듈을 추가할 수도 있습니다.쿼리를 실행 중인 소프트웨어(예: "TOAD 9.0.1.8", "JDBC Thin Client", "runcbl@somebox(TNS V1-V3)" 등)에 대해 모듈이 잘못된 단서를 제공하는 경우가 많습니다.

SELECT 
 module, 
 sql_text, 
 username, 
 disk_reads_per_exec, 
 buffer_gets, 
 disk_reads, 
 parse_calls, 
 sorts, 
 executions, 
 rows_processed, 
 hit_ratio, 
 first_load_time, 
 sharable_mem, 
 persistent_mem, 
 runtime_mem, 
 cpu_time, 
 elapsed_time, 
 address, 
 hash_value 
FROM 
  (SELECT
   module, 
   sql_text , 
   u.username , 
   round((s.disk_reads/decode(s.executions,0,1, s.executions)),2)  disk_reads_per_exec, 
   s.disk_reads , 
   s.buffer_gets , 
   s.parse_calls , 
   s.sorts , 
   s.executions , 
   s.rows_processed , 
   100 - round(100 *  s.disk_reads/greatest(s.buffer_gets,1),2) hit_ratio, 
   s.first_load_time , 
   sharable_mem , 
   persistent_mem , 
   runtime_mem, 
   cpu_time, 
   elapsed_time, 
   address, 
   hash_value 
  FROM
   sys.v_$sql s, 
   sys.all_users u 
  WHERE
   s.parsing_user_id=u.user_id 
   and UPPER(u.username) not in ('SYS','SYSTEM') 
  ORDER BY
   4 desc) 
WHERE
 rownum <= 20;

쿼리가 길면 에 주의하십시오.v_$sqltext를 쿼리해야 합니다.이렇게 하면 전체 쿼리가 저장됩니다.주소와 HASH_VALUE를 조회하여 모든 조각을 픽업해야 합니다.예:

SELECT
 *
FROM
 sys.v_$sqltext
WHERE
 address = 'C0000000372B3C28'
 and hash_value = '1272580459'
ORDER BY 
 address, hash_value, command_type, piece
;

답변이 짧아서 죄송합니다만 늦었습니다.Google "오라클 이벤트 10046 sql 추적".v$sql에서 어떤 SQL이 어떤 세션에 속하는지 확인하는 것은 공유 SQL이고 여러 사용자가 사용하는 경우 쉽지 않기 때문에 개별 세션을 추적하는 것이 가장 좋습니다.

Oracle DBA 친구들에게 깊은 인상을 주고 싶다면 이벤트 10046으로 Oracle 추적을 설정하고, 대기 이벤트의 의미를 해석하고, 상위 CPU 소비자를 찾는 방법에 대해 알아봅니다.

Quest에는 클라이언트 측에서 SQL을 캡처할 수 있는 무료 제품이 있었지만, 해당 제품/Oracle 버전에서 작동하는지는 확실하지 않습니다.이를 위한 구글 "quest oracle sql monitor".

안녕히 주무세요.

V$SQL AREA 테이블에는 원하는 항목이 포함되어 있습니다(SQL_TEXTSQL_FULLTEXT 열 참조).

네, 그건 확실히 가능합니다.v$sql 보기에는 해당 정보가 포함되어 있습니다.코드 조각과 같은 것이 올바른 방향을 가리켜 줄 것입니다.저는 Oracle DB 근처에 있는 특정 코드를 직접 시도해 본 적이 없습니다.

[편집] 벌써 두 개의 답이 나왔습니다.다음 번에는 더 빨리 입력해야 합니다 ;-)

저는 이것과 같은 것을 사용하는데, 컨셉과 약간의 코드를 요청톰에서 도용했습니다.
을 위한 은 환영합니다.

와 함께
AS를 평가합니다.
(
선택*
시작 V$ 세션
사용자 이름 = 사용자 이름
SID별 주문
)
SELECTsi. 에서 확인할 수 .SID,
si.잠금 대기,
si.OS 사용자,
si.프로그램,
si.LOGON_TIME,
si.상태,
(
라운드 선택(USED_UBLK*8/1024,1)
V$ 트랜잭션에서,
쎄스
파일 이름은 TADDR =입니다.TADDR = V$TRANSACTION.ADDR
그리고 sess.SID = si.SID

) rollback_filename,

(
선택(MAX(DECODE(PIECE(PIECE, 0,SQL_TEXT, NULL)) ||
MAX(DECODE(PIECE, 1,SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 2, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 3, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 4, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 5, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 6, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 7, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 8, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 9, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 10, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 11, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 12, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 13, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 14, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 15, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 16, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 17, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 18,SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 19, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 20, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 21, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 22, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 23, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 24, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 25, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 26, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 27, SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 28,SQL_TEXT, NULL) ||
MAX(DECODE(PIECE, 29, SQL_TEXT, NULL))
원본 V$SQLTEXT_WITH_NEWLINES
WHERE ADDRESS = SI.SQL_ADDRESS AND
PIECE < 30
) SQL_TEXT
sessi로부터;

자바 애플리케이션에서도 비슷한 문제가 있었습니다.Oracle 드라이버 주변에 JDBC 드라이버 래퍼를 작성하여 모든 출력이 로그 파일로 전송됩니다.

언급URL : https://stackoverflow.com/questions/55899/how-to-see-the-actual-oracle-sql-statement-that-is-being-executed

반응형