-- SQL 모니터 레포트 확인 SELECT DBMS_SQLTUNE.REPORT_SQL_MONITOR( sql_id =>'sql_id_here', type =>'TEXT' ) FROM DUAL;
운영 환경에서 실행된 쿼리의 실행 계획 조회
운영 중인 환경에서는 여러 쿼리가 동시에 실행되므로, 특정 쿼리의 실행 계획을 정확히 추출하는 것이 중요합니다.
방법 1: SQL_ID를 이용한 조회 (가장 추천)
-- 1단계: 실행할 쿼리에 고유 식별자 추가 SELECT/* MY_UNIQUE_QUERY_20260106 */* FROM employees WHERE department_id =10;
-- 2단계: SQL_ID 찾기 SELECT sql_id, sql_text, executions, last_active_time FROM v$sql WHERE sql_text LIKE'%MY_UNIQUE_QUERY_20260106%' AND sql_text NOTLIKE'%v$sql%'; -- 이 조회문 자체 제외
-- 3단계: SQL_ID로 실제 실행 계획 조회 SELECT*FROMTABLE(DBMS_XPLAN.DISPLAY_CURSOR('sql_id_here', NULL, 'ALLSTATS LAST'));
-- 실행 통계까지 포함된 상세 계획 SELECT*FROMTABLE(DBMS_XPLAN.DISPLAY_CURSOR('sql_id_here', NULL, 'ADVANCED ALLSTATS LAST'));
방법 2: GATHER_PLAN_STATISTICS 힌트 사용
-- 실행 계획 수집 힌트 추가하여 쿼리 실행 SELECT/*+ GATHER_PLAN_STATISTICS MY_QUERY_001 */* FROM employees e JOIN departments d ON e.department_id = d.department_id WHERE e.salary >10000;
-- SQL_ID 찾기 SELECT sql_id, child_number, sql_text FROM v$sql WHERE sql_text LIKE'%MY_QUERY_001%' AND sql_text NOTLIKE'%v$sql%';
-- 실제 실행 통계가 포함된 계획 조회 SELECT*FROMTABLE(DBMS_XPLAN.DISPLAY_CURSOR('발견된_sql_id', NULL, 'ALLSTATS LAST'));
방법 3: 세션 레벨 추적
-- 현재 세션에서만 통계 수집 활성화 ALTER SESSION SET STATISTICS_LEVEL =ALL;
-- 쿼리 실행 SELECT*FROM employees WHERE department_id =10;
-- 마지막 실행된 쿼리의 SQL_ID 조회 SELECT prev_sql_id, prev_child_number FROM v$session WHERE sid = (SELECT sid FROM v$mystat WHERE ROWNUM =1);
-- 실행 계획 조회 SELECT*FROMTABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL, NULL, 'ALLSTATS LAST'));
-- 통계 수집 원복 ALTER SESSION SET STATISTICS_LEVEL = TYPICAL;
방법 4: SQL 해시값으로 추적
-- 쿼리 텍스트의 해시값 미리 계산 SELECT DBMS_UTILITY.GET_SQL_HASH(' SELECT * FROM employees WHERE department_id = 10 ', NULL, 1) as sql_hash FROM DUAL;
-- 쿼리 실행 후 해시값으로 찾기 SELECT sql_id, sql_text, executions, last_active_time FROM v$sql WHERE hash_value ='위에서_계산한_해시값';
-- 실행 계획 조회 SELECT*FROMTABLE(DBMS_XPLAN.DISPLAY_CURSOR('sql_id', NULL, 'ALLSTATS LAST'));
방법 5: AWR에서 과거 실행 계획 조회
-- AWR에 저장된 SQL 찾기 SELECT sql_id, snap_id, plan_hash_value, executions_delta FROM dba_hist_sqlstat WHERE sql_id ='your_sql_id' ORDERBY snap_id DESC;
-- AWR에서 실행 계획 조회 SELECT*FROMTABLE(DBMS_XPLAN.DISPLAY_AWR('sql_id', 'plan_hash_value'));
실전 팁
-- 실시간 실행 중인 쿼리 모니터링 SELECT s.sid, s.serial#, s.username, s.sql_id, q.sql_text, s.last_call_et, s.status FROM v$session s JOIN v$sql q ON s.sql_id = q.sql_id WHERE s.username ISNOTNULL AND s.status ='ACTIVE' ORDERBY s.last_call_et DESC;
-- 특정 세션의 현재 실행 중인 SQL 계획 SELECT*FROMTABLE(DBMS_XPLAN.DISPLAY_CURSOR( (SELECT sql_id FROM v$session WHERE sid ='특정_sid'), NULL, 'ALLSTATS LAST' ));
-- SQL_ID로 모든 child cursor의 계획 조회 SELECT*FROMTABLE(DBMS_XPLAN.DISPLAY_CURSOR('sql_id', NULL, 'ALLSTATS LAST'));
-- SQL Baseline이 있는 경우 계획 조회 SELECT*FROMTABLE(DBMS_XPLAN.DISPLAY_SQL_PLAN_BASELINE( sql_handle =>'sql_handle', plan_name =>NULL, format =>'TYPICAL' ));