자바 소스에서 디버깅을 할 때 아래와 같이 진행한다.

 

1. 디버깅 하고 싶은 자바 소스에서 줄번호 더블 클릭하여 breakpoints를 찍는다.

 

2. tomcat Debug mode 로 start

 

3. breakpoints 를 찍은 소스 부분이 실행될 때, 해당 변수들의 value 확인 가능함.

 - 변수들의 value 확인이 가능하고, 메소드의 결과는 확인할 수 없다.

 - F8 : 다음 breakpoint 로 이동

 

4. 메소드 결과 확인하는 방법

 - breakpoint 찍은 라인에 메소드 결과를 확인하고 싶은 경우 해당 메소드를 아래 사진과 같이 입력하면 결과(false)를 확인 할 수 있다.

 

클러스터 인덱스, 넌클러스터 인덱스

클러스터 인덱스 : Oracle에서 IOT(Index Organized Table)와 동일한 개념이다.

넌클러스터 인덱스 : Oracle에서 일반 인덱스(Non-unique Index)와 동일한 개념이다.

 

참고로 오라클에서는 상대적으로 IOT를 잘 사용하지 않는다.

 

※ 클러스터 인덱스 설명 URL : https://leechun.tistory.com/41?category=983198

 

Oracle Index 종류

단일 인덱스(Single column Index) : 인덱스에 하나의 컬럼만 사용

결합 인덱스(Composite Index) : 인덱스에 두 개 이상의 컬럼을 사용

 

PK 속성은 단일 인덱스로 구성할 수 있고, 결합 인덱스로 구성될 수 있다.

 

Oracle Index 분류

유니크 인덱스(Unique Index) : 인덱스 구성 컬럼들 값에 중복을 허용하지 않는다.

비유니크 인덱스(Non-unique Index) : 인덱스 구성 컬럼들 값에 중복을 허용한다.

 

PK 제약 조건으로 컬럼을 선택한다면, 무조건 유니크 인덱스가 구성된다.

 

Oracle Index 물리적인 구조

B*트리 인덱스 : 트리 형태의 자료 구조를 사용함 (대부분 B*트리 사용함)

비트맵 인덱스 : 값의 종류가 많지 않은 컬럼에 사용함

 

Oracle 파티션 된 Index 구분

글로벌 인덱스

로컬 인덱스

 

Oracle 제약사항 조회
SELECT DECODE(A.CONSTRAINT_TYPE,  'P', 'Primary Key',  'R', 'Foreign Key', 
             'C', 'Table Check',  'V', 'View Check',  'U', 'Unique',  '?') AS "유형"
     , SUBSTRB(A.CONSTRAINT_NAME, 1, 25) AS CONSTRAINT_NAME
     , B.POSITION
     , SUBSTRB(B.COLUMN_NAME, 1, 25) AS COLUMN_NAME
  FROM DBA_CONSTRAINTS A
     , DBA_CONS_COLUMNS B
 WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME
-- AND A.OWNER = 'MAFCCC'
   AND A.TABLE_NAME = UPPER('테이블 이름')
 ORDER BY  1, 2, 3;

Oracle에서 성능 개선을 위해 실행계획을 사용한다.

아래와 같이 실행계획은 예상 실행계획과 실제 실행계획 방법을 살펴보자

 

예상 실행계획

Toad, Orange와 같은 Tool에서는 "ctrl+e" 눌러서 예상 실행계획을 편하게 확인하는 경우가 있으나 자세한 정보를 보기 위해서는 아래와 같이 따라한다.

 

SELECT * FROM T_ORD WHERE ORD_SEQ = 4;

위 쿼리를 예상 실행계획으로 실행하고 싶은 경우엔 아래와 같이 실행한다.

 

-- 실행계획 만들기
EXPLAIN PLAN FOR
SELECT * FROM T_ORD WHERE ORD_SEQ = 4;

-- 실행계획 확인하기
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());

위와 같이 쿼리 2문장을 순서대로 각각 실행하면 아래와 같이 예상 실행계획 결과가 나온다.

 

PLAN_TABLE_OUTPUT
 
-----------------------------------------------------------------------------
| Id  | Operation                   | Name     | Rows  | Bytes | Cost (%CPU)|
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |          |     1 |    44 |     2   (0)|
|   1 |  TABLE ACCESS BY INDEX ROWID| T_ORD    |     1 |    44 |     2   (0)|
|*  2 |   INDEX UNIQUE SCAN         | PK_T_ORD |     1 |       |     1   (0)|
-----------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - access("ORD_SEQ"=4)
-- Id : 실행계획의 오퍼레이션 ID (구분자, 순서아님)
-- Operation : 해당 단계에 수행한 작업 내용
-- Name : 해당 단계에 작업을 수행한 대상 오브젝트(테이블 또는 인덱스)
-- Rows : 해당 단계 수행 시 조회될 예상 데이터 건수
-- Bytes : 해당 단계까지 사용될 예상 데이터양(누적)
-- Cost (%CPU) : 해당 단계까지 사용될 예상 비용(누적)

 

실제 실행계획
SELECT *
  FROM T_ORD T1
     , M_CUS T2
 WHERE T1.CUS_ID = T2.CUS_ID
   AND T1.ORD_DT >= TO_DATE('20170101','YYYYMMDD')
   AND T1.ORD_DT < TO_DATE('20170201','YYYYMMDD')
   AND T2.CUS_GD = 'A';

위 쿼리를 실제 실행계획으로 실행하고 싶은 경우엔 아래와 같이 실행한다.

 

1번 : 실제 실행계획 만들기(hint 추가)

SELECT /*+ GATHER_PLAN_STATISTICS */
       *
  FROM T_ORD T1
     , M_CUS T2
 WHERE T1.CUS_ID = T2.CUS_ID
   AND T1.ORD_DT >= TO_DATE('20170101','YYYYMMDD')
   AND T1.ORD_DT < TO_DATE('20170201','YYYYMMDD')
   AND T2.CUS_GD = 'A';

 

2번 : 실제 실행계획을 만든 SQL의 SQL_ID찾아내기

SELECT T1.SQL_ID ,T1.CHILD_NUMBER ,T1.SQL_TEXT
  FROM V$SQL T1
 WHERE T1.SQL_TEXT LIKE '%GATHER_PLAN_STATISTICS%'
 ORDER BY T1.LAST_ACTIVE_TIME DESC;

 

3번 : 실제 실행계획 조회하기(각자의 SQL_ID, CHILD_NUMBER를 사용할 것)

SELECT *
  FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('3ykn80uy9n32d',0,'ALLSTATS LAST'));

 

위와 같이 1~3번 쿼리를 순서대로 실행하면 아래와 같이 실제 실행계획 결과가 나온다.

PLAN_TABLE_OUTPUT
SQL_ID  3ykn80uy9n32d, child number 0
-------------------------------------
SELECT /*+ GATHER_PLAN_STATISTICS */        *   FROM T_ORD T1      , 
M_CUS T2  WHERE T1.CUS_ID = T2.CUS_ID    AND T1.ORD_DT >= 
TO_DATE('20170101','YYYYMMDD')    AND T1.ORD_DT < 
TO_DATE('20170201','YYYYMMDD')    AND T2.CUS_GD = 'A'
 
Plan hash value: 3240201901
 
-----------------------------------------------------------------------------------------------------------------
| Id  | Operation          | Name  | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |       |      1 |        |    101 |00:00:00.01 |      12 |       |       |          |
|*  1 |  HASH JOIN         |       |      1 |    170 |    101 |00:00:00.01 |      12 |   779K|   779K| 1234K (0)|
|*  2 |   TABLE ACCESS FULL| M_CUS |      1 |     60 |     60 |00:00:00.01 |       7 |       |       |          |
|*  3 |   TABLE ACCESS FULL| T_ORD |      1 |    252 |    146 |00:00:00.01 |       5 |       |       |          |
-----------------------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - access("T1"."CUS_ID"="T2"."CUS_ID")
   2 - filter("T2"."CUS_GD"='A')
   3 - filter(("T1"."ORD_DT"<TO_DATE(' 2017-02-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND 
              "T1"."ORD_DT">=TO_DATE(' 2017-01-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss')))
-- Starts : 해당 단계를 수행한 횟수
-- E-Rows : 해당 단계의 예상 데이터 건수
-- A-Rows : 해당 단계의 실제 데이터 건수
-- A-Time : 해당 단계까지 수행된 실제 시간(누적)
-- Buffers : 해당 단계까지 메모리 버퍼에서 읽은 블록 수(논리적 IO 횟수, 누적)
-- Reads : 해당 단계까지 디스크에서 읽은 블록 수(물리적 IO 횟수, 누적)
-- OMem : SQL 처리를 위해 사용한 메모리 수치
-- 1Mem : SQL 처리를 위해 사용한 메모리 수치
-- Used-Mem : SQL 처리를 위해 사용한 메모리 수치

끝.

'DB > Oracle' 카테고리의 다른 글

Orange, Toad 에서 Parameter 확인 방법  (0) 2022.04.13
Oracle INDEX  (0) 2022.03.10
CONNECT BY LEVEL  (0) 2021.12.31
ORA-12899: value too large for column, 오라클 문자열 길이 구하기  (0) 2021.12.14
TRUNC(값, 옵션)  (0) 2021.11.04

+ Recent posts