#1.SQL초보에서 Schema Objects까지(SQL학원/오라클학원/IT실무교육학원/재직자/실업자교육학원추천)탑크리에듀(구로디지털단지역3번출구 2분거리)탑크리에듀교육센터(topcredu.co.kr)제공
1-1. 오라클, 데이터베이스관련 용어, 1-2. 오라클 에디션(ORACLE EDITION), 1-3. 오라클 버전 변화 등.. 개요 및 실습데이터 설치에 관련하여 설명 한 자료입니다. 많은 도움 되시길 바랍니다.^^
오라클 커서(Cursor) 개념 및 오라클 메모리 구조_PL/SQL,오라클커서강좌,SGA, PGA, UGA, Shared Pool, Sha...탑크리에듀(구로디지털단지역3번출구 2분거리)탑크리에듀(http://www.topcredu.co.kr)에서 제공하는 오라클, SQL, PL/SQL, 힌트튜닝 강좌중 오라클 커서(Cursor) 개념 & 메모리 구조(Memory Strucre)와 관련된 PPT 강좌 입니다. CURSOR, PGA, UGA, Shared Server, Dedicate Server, DRCP, Library Cache, Shared SQL Area와 관련된 내용 참조하시기 바랍니다.
(오라클SQL강좌)오라클 NLS 파라미터_NLS_DATE_FORMAT, NLS_LANG, NLS_LANGUAGE, NLS_TERRITORY...탑크리에듀(구로디지털단지역3번출구 2분거리)탑크리에듀(http://www.topcredu.co.kr), 오라클자바커뮤니티(http://ojc.asia) 제공 오라클 SQL기초 강좌중 NLS 파라미터와 관련된 강좌 입니다. 본원 웹페이지에 오시면 다양한 슬라이드 강좌 및 동영상 강좌 보실 수 있으니 참조하세요
#1.SQL초보에서 Schema Objects까지(SQL학원/오라클학원/IT실무교육학원/재직자/실업자교육학원추천)탑크리에듀(구로디지털단지역3번출구 2분거리)탑크리에듀교육센터(topcredu.co.kr)제공
1-1. 오라클, 데이터베이스관련 용어, 1-2. 오라클 에디션(ORACLE EDITION), 1-3. 오라클 버전 변화 등.. 개요 및 실습데이터 설치에 관련하여 설명 한 자료입니다. 많은 도움 되시길 바랍니다.^^
오라클 커서(Cursor) 개념 및 오라클 메모리 구조_PL/SQL,오라클커서강좌,SGA, PGA, UGA, Shared Pool, Sha...탑크리에듀(구로디지털단지역3번출구 2분거리)탑크리에듀(http://www.topcredu.co.kr)에서 제공하는 오라클, SQL, PL/SQL, 힌트튜닝 강좌중 오라클 커서(Cursor) 개념 & 메모리 구조(Memory Strucre)와 관련된 PPT 강좌 입니다. CURSOR, PGA, UGA, Shared Server, Dedicate Server, DRCP, Library Cache, Shared SQL Area와 관련된 내용 참조하시기 바랍니다.
(오라클SQL강좌)오라클 NLS 파라미터_NLS_DATE_FORMAT, NLS_LANG, NLS_LANGUAGE, NLS_TERRITORY...탑크리에듀(구로디지털단지역3번출구 2분거리)탑크리에듀(http://www.topcredu.co.kr), 오라클자바커뮤니티(http://ojc.asia) 제공 오라클 SQL기초 강좌중 NLS 파라미터와 관련된 강좌 입니다. 본원 웹페이지에 오시면 다양한 슬라이드 강좌 및 동영상 강좌 보실 수 있으니 참조하세요
#25.SQL초보에서 Schema Objects까지_구로IT학원/국비지원IT학원추천/구로디지털단지IT학원/재직자환급교육추천탑크리에듀(구로디지털단지역3번출구 2분거리)탑크리에듀교육센터(topcredu.co.kr)에서 제공하는 자료입니다.
SQL초보에서 Schema Objects까지 25번째 자료입니다.
단일/복합(결합) 인덱스(Single Column/Composite Index),고유/비고유 인덱스(Unique/Non Unique Index), Descending Index, 함수기반 인덱스(Function Based Index), 인덱스 재구성 및 삭제, 인덱스 숨기기(Index Invisible)에 대하여 설명한 자료이오니 확인 후 많은 도움 되셨길 바랍니다^^.
6.2 hints for access paths(cluster)탑크리에듀(구로디지털단지역3번출구 2분거리)인덱스 클러스터란(Index Cluster) ?
클러스터 내의 데이터를 유지하기 위해 클러스터 인덱스라는 인덱스 사용
클러스터 인덱스는 주어진 키 값을 가진 행을 포함하고 있는 블록을 가리키는데 사용된다.
클러스터 인덱스의 구조는 보통 인덱스의 구조와 비슷하다. (보통 인덱스는 NULL 키 값을 저장하지 않지만 클러스터 인덱스는 NULL 키를 저장)
클러스터로부터 행을 저장하고 읽어 들이기 위해 오라클 서버는 주어진 키 값을 갖는 첫 행을 가리키는 클러스터 인덱스를 사용
5.2 비트맵 인덱스탑크리에듀(구로디지털단지역3번출구 2분거리)[BITMAP INDEX]
정보저장의 최소단위인 비트를 이용하여 칼럼 값을 간결하게 저장하고 이를 이용하여 자동으로 ROWID를 생성하는 구조를 가지며 분포도가 나쁜 칼럼, NOT, OR를 사용하는 경우 탁월한 성능을 낸다.
비트맵 인덱스를 생성하면 비트리 인덱스처럼 트리구조를 만들고 리프블럭에 값들을 비트로 변환하여 저장한다. 비트리 인덱스의 리프 블록(Leaf Block)은 INDEX KEY VALUE와 ROWID 로 구성이 되어 있지만 비트맵 인덱스는 START ROWID~END ROWID로 압축해서 저장하고 칼럼값 역시 ‘1’ 이라는 비트로 저장해서 원본 데이터의 ROWID를 계산한다.
인덱스를 Bit 단위로 저장(데이터의 존재 여부를 0 or 1로 표시)하고 비트리 인덱스 한계를 극복하여 대량의 자료 조회에 적합한 구조이지만 잦은 DML이 발생되는 곳은 리프 블록(Leaf Block)의 갱신으로 인해 부적합하다. 하나의 인덱스 값을 수정하면 그 인덱스 값을 가지는 모든 로우에 락을 건다. 즉 하나의 인덱스 값으로 테이블상의 여러 개의 행을 표현하기 때문에 INSERT, UPDATE, DELETE 등을 사용하는 경우 오라클 락 메커니즘인 행 단위 락(ROW LEVEL LOCKING)을 지원할 수 없다.
B*Tree 인덱스가 NULL값을 보관하지 않는 것과는 달리 Bitmap 인덱스는 NULL값에 대한 BIT값을 저장하여 비트리 인덱스의 NULL문제를 해결했으며 AND, OR 연산시 비트연산을 빠르게 수행한다.
생성 절차 : 인덱스를 생성하고자 하는 테이블 스캔을 한 후 Bitmap Index Generator에 의해 칼럼 값(비트형태의 ‘1’로 저장), 시작 ROWID, 끝 ROWID , Bitmap을 갖는 인덱스 엔트리를 생성한다. 생성된 Bitmap들을 B-tree구조에 넣기 쉽도록 key값과 start rowid 순으로 정렬하며 마지막 단계에서는 정렬된 인덱스 엔트리들을 단순히 B-tree구조로 삽입한다.
#23.SQL초보에서 Schema Objects까지_SQL기초교육/오라클교육/국비지원환급교육/재직자교육/구로IT학원추천탑크리에듀(구로디지털단지역3번출구 2분거리)탑크리에듀교육센터(topcredu.co.kr)에서 제공하는
데이터 딕셔너리 개요, USER_ 데이터 딕셔너리 뷰에 대해 설명한 자료입니다.
3.2 실행계획 sql 연산 (concatenation)탑크리에듀(구로디지털단지역3번출구 2분거리)-- 먼저 EMP에 테이블에 생성되어 있는 인덱스 및 칼럼을 확인하자.
SQL> SELECT a.index_name, a.column_name, b.visibility
FROM user_ind_columns a, user_indexes b
WHERE a.table_name = 'EMP'
AND a.index_name = b.index_name ;
-- 인덱스가 없다면 생성, 있으면 SKIP
SQL> CREATE INDEX idx_emp_job ON EMP(job);
SQL> CREATE INDEX idx_emp_deptno ON EMP(deptno);
5.3 비트맵 조인 인덱스탑크리에듀(구로디지털단지역3번출구 2분거리) 비트맵 조인 인덱스(BITMAP JOIN INDEX)란? 두 테이블 조인시 조인한 결과 칼럼에 대해 비트맵 인덱스를 생성하는 것이다.
예를 들어 EMP, DEPT 테이블을 DEPTNO(FK, PK) 칼럼으로 조인하면서 DEPT의 DNAME을 WHERE절에서 사용한다고 가정하자. 조인 조건으로 DEPT의 DNAME칼럼에 대해 비트맵 인덱스를 생성해 두고 EMP, DEPT조인하여 부서명(DNAME)을 가져와야 하는 경우 실제 조인을 수행하지 않고 비트맵 인덱스를 이용하여 부서명을 빠르게 가져올 수 있다.
PK(UK), FK 관계를 가진 테이블에서만 생성 가능한 인덱스이다.
3.6 실행계획 SQL 연산 (NESTED LOOP SEMI-JOIN)탑크리에듀(구로디지털단지역3번출구 2분거리)WHERE절에 인덱스 구성 컬럼이 ‘<’>’와 같이 범위 제한 연산자에 의해 이용되거나 BETWEEN or LIKE와 같은 조건 절에 이용될 때 INDEX RANGE SCAN을 하게 된다. 만약 결합(복합) 인덱스라면 범위 제한자에 사용되는 컬럼은 인덱스 구성 컬럼 중 선두 컬럼이여야 한다. 조건을 만족하는 첫 번째 레코드를 인덱스 블록에서 추출 후 조건에 맞는 데이터가 나올 때 까지 계속 스캔하는 나가는 방식으로 INDEX, INDEX_ASC 힌트를 사용할 때 나타나는 연산자이다.
아래 예에서 EMP TABLE에는 sal에 대해 오름차순 순방향 인덱스가 구성되어 있다.
(Index Range Scan이 가능하도록 하는 힌트는 INDEX_RS 이다.)
2.1 optimizer mode를 변경하는 힌트(rule)탑크리에듀(구로디지털단지역3번출구 2분거리)규칙 기반 옵티마이저(Rule-Based Optimizer)로 동작하여 실행 계획을 세우도록 하는 힌트인데 이 경우 테이블이나 인덱스의 통계 정보가 있다고 하더라도 무시하고 사용하지 않으며 규칙에 기반한 실행 계획을 세우게 된다.
옵티마이저는 순위가 매겨진 오퍼레이션에 근거하여 실행 계획을 세우며 순위가 높은 것이 우선 적용된다.
만약 SQL 문장에서 /*+ RULE INDEX(emp idx_ename) */ 와 같이 RULE 힌트와 다른 힌트가 같이 사용된다면 RULE 힌트만 적용되므로 주의하자.
1.3 dbms stats 패키지사용하기탑크리에듀(구로디지털단지역3번출구 2분거리) DBMS_STATS 패키지에는 몇 개의 유용한 프러시저가 있는데 아래와 같다.
gather_database_ stats: 데이터베이스의 모든 Object에 대한 통계 정보 생성.
gather_schema_ stats: 해당 스키마의 모든 Object에 대한 통계 정보 생성.
gather_table_stats : 테이블과 그 테이블과 연관된 인덱스에 대한 통계 정보 생성.
gather_index_stats : 인덱스에 대해 통계 정보를 생성.
1.7 튜닝의도구 sql autorace탑크리에듀(구로디지털단지역3번출구 2분거리)SQL*Plus에서 사용자는 자동으로 Optimizer가 만드는 실행계획과 통계정보를 얻을 수 있다. 이런 경우 AUTOTRACE를 사용하며 DML문을 성공적으로 수행 시 실행계획과 통계정보가 만들어지며 DML문의 성능 튜닝을 위한 방법으로 자주 이용된다.
SET AUTOTRACE를 사용하기 위해선 실행 계획용 테이블(PLAN_TABLE)이 존재해야 하며 구문을 활성화하기 위해 SET AUTOTRACE ON, 비활성화 하기 위해 SET AUTOTRACE OFF하면 된다. 참고로 SET AUTOTRACE에서 사용할 수 있는 옵션은 다음과 같다.
3.4 실행계획 SQL 연산 (Hash Anti-Join)탑크리에듀(구로디지털단지역3번출구 2분거리)ANTI 조인은 조인의 대상이 되는 테이블과 일치하지 않는 데이터를 추출하는 연산으로 SQL연산에서 NOT IN, NOT EXISTS, MINUS 등이 있을 때 나타나는 실행계획 연산자이다. 안티 조인은 NESTED LOOP ANTI-JOIN, MERGE ANTI-JOIN 또는 HASH ANTI_JOIN으로 풀리도록 할 수 있는데 대체로 HASH ANTI_JOIN이 성능상 좋다.
1. Part 1 ORACLE │173
SQL 튜닝에 Dictionary View 활용하기 - Part2
㈜엑셈 컨설팅본부/DB컨설팅팀 정 동기
개요
SQL 성능을 개선하기 위해서는 판단할 수 있는 근거를 수집하는 작업이 중요하다. SQL 에 사용
된 관련 테이블 정보 및 인덱스 정보들을 수집하여 종합적으로 판단 해야만 좀더 효율적인 성능
개선을 이끌어 낼 수 있기 때문이다. 오라클은 이러한 정보들을 Dictionary View 를 통해서 사
용자에게 전달 하고 있다. 그 중 이번 화이트 페이퍼에서는 테이블과 인덱스 관련 정보를 토대로
SQL 성능 개선에 어떻게 활용되는 지를 서술하고 있다.
테이블, 인덱스 통계를 활용 개선 사례
테이블과 인덱스 관련 정보들은 Dictionary View 를 통해서 살펴 볼 수 있다. 오라클은
DBA_TABLES, DBA_TAB_COLUMNS, DBA_INDEXES, DBA_IND_COLUMNS,
DBA_IND_EXPRESSIONS 의 View 들을 통해서 관련 정보들을 검색 활용 할 수 있도록 제공하
고 있다. 그렇다면 테스트를 통해 해당 View 들이 어떻게 활용 되는지를 알아 보도록 하자.
인덱스 효율성 판단 사례
SELECT c1 ,
c2 ,
c3 ,
c4 ,
c5 ,
c6
FROM dict_view_t1 t
WHERE c2 = 'B'
AND c3 = '11'
AND c4 = 'RED'
2. 174│2013 기술백서 White Paper
AND c5 = '1981'
AND C1 = 1
-------------------------------------------------------------------------------------
| Id | Operation | Name |Starts| E-Rows | A-Rows | A-Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 | 00:00:00.02 |
|* 1 | TABLE ACCESS FULL|DICT_VIEW_T1 | 1 | 1 | 1 | 00:00:00.02 |
-------------------------------------------------------------------------------------
해당 SQL 의 실행 계획을 살펴 보면 총 추출 건수 가 1 건으로 매우 적지만 TABLE FULL SCAN
을 통하여 정보를 추출하고 있으므로 효율적인지를 판단해 볼 필요성이 있다. 그렇다면 TABLE
FULL SCAN 이 효율적인 것인지 그렇지 않다면 해당 TABLE 에 적합한 인덱스가 존재 하는지,
인덱스가 존재 한다면 어떠한 인덱스가 효율적인 지를 따져봐야 할 것이다. 오라클은 관련
Dictionary View 를 통해서 해당 자료들을 제공하고 있다.
우선 테이블 인덱스 존재 여부는 DBA_INDEXES 를 통해서 확인 가능하다.
[Script 3 수행 결과]
INDEX_NAME U TABLESPACE DISTINCT CLUSTERING FACTOR BLEVEL LEAF_BLK
--------------------------- - ---------- --------- ------------------ ------ ---------
DICT_VIEW_T1_IDX_01(SH) N USERS 1000000 3377 2 2226
DICT_VIEW_T1_IDX_02(SH) N USERS 10 33770 2 3540
또한 해당 인덱스의 구성 칼럼 정보들은 DBA_IND_COLUMNS 를 통해서 살펴볼 수 있다.
[Script 4 수행 결과]
INDEX_NAME TYPE U COLUMN LIST
-------------------- ---- -- --------------
DICT_VIEW_T1_IDX_01 NORM N C1
DICT_VIEW_T1_IDX_02 NORM N C2, C3, C4, C5
그리고 인덱스 구성 칼럼의 CARDINALITY 나 DISTINCT VALUE 등을 살펴 보기 위해서는
DBA_TABLES 와 DBA_TAB_COLUMNS 를 통해서 관련 정보를 얻을 수 있다.
3. Part 1 ORACLE │175
CARDINALITY = ( DBA_TABLES.NUM_ROWS – DBA_TAB_COLUMN.NUM_NULLS ) /
DBA_TAB_COLUMNS.NUM_DISTINCT
[활용 Script 1 결과]
TABLE NAME TABLESPACE NAME NUM_ROWS DEGREE BLOCKS
---------------- --------------- -------- ------ ------
DICT_VIEW_T1(SH) USERS 1000000 1 3439
[활용 Script 2 결과]
COLUMN_NAME DATA_TYPE DATALEN NN DISTINCT DENSITY NUM_NULLS BUCKET SAMPLE_SIZE
------------ -------- ---------- -- --------- ----------- ---------- ------ ----------
C1 NUMBER 22 N 1000000 0.000001000 0 1 1000000
C2 VARCHAR2 1 Y 2 0.500000000 0 1 1000000
C3 NUMBER 22 Y 10 0.100000000 0 1 1000000
C4 VARCHAR2 5 Y 5 0.200000000 0 1 1000000
C5 NUMBER 22 Y 10 0.100000000 0 1 1000000
이렇게 해당 Dictionary View 을 통해서 관련 정보들을 제공 받을 수 있다. 우리는 이러한 정보
들을 활용하여 성능 문제를 개선하기 위한 판단 근거로 활용 할 수 있다. 그렇다면 해당 SQL 의
관련 정보들을 활용하여 효율성을 판단해 보도록 하자. 먼저 SQL 의 WHERE 조건 절을 살펴 보
면 검색 조건으로 C1 ~C5 까지 존재 한다. 또한 TABLE DICT_VIEW_T1 에는 2 개의 인덱스가
존재하는 것을 Dictionary View 를 통해서 확인 하였다. 먼저 2 개의 인덱스
DICT_VIEW_T1_IDX_01, DICT_VIEW_T1_IDX_02 중 어떠한 인덱스가 효율적인 지를 판단
해 보도록 하자. 인덱스 DICT_VIEW_T1_IDX_01 은 칼럼 C1 으로 구성되어 있다. C1 의
CARDINALITY 를 살펴보면 (1000000 – 0) / 1000000 = 1 로 매우 효율적인 것을 확인 할 수
있다. 즉 TABLE DICT_VIEW_T1 의 NUM_ ROWS 값이 1000000 이고 인덱스
DICT_VIEW_T1_IDX_01 의 DISTINCT 값이 1000000 이므로 인덱스 평균 추출 건수가
(1000000/1000000 = 1) 약 1 건이라는 것을 판단 할 수 있다. 이번에는 인덱스
DICT_VIEW_T1_IDX_02 의 효율성을 확인해 보도록 하자. DICT_VIEW_T1_IDX_02 의 구성
칼럼은 C2, C3, C4, C5 로 구성되어 있다. 인덱스 DICT_VIEW_T1_IDX_02 구성 칼럼에 각각
의 CARDINALITY 는 C2 =(10000000 – 0) / 2 = 5000000, C3 =(10000000 – 0) / 10 =
4. 176│2013 기술백서 White Paper
1000000, C4 = (10000000 – 0) / 5 = 2000000, C5 = (10000000 – 0) / 10 = 1000000
이다. 인덱스 DICT_VIEW_T1_IDX_02 구성 칼럼의 CARDINALITY 는 C1 칼럼에 비해 매우
비효율 적인 것을 확인 할 수 있다. 다시 말해서 TABLE 의 NUM_ROWS 값이 1000000 이고 인
덱스 DICT_VIEW_T1_IDX_02 의 DISTINCT 값이 10 이므로 1000000/10 = 100000 이므
로 인덱스 평균 추출 건수가 약 100000 건으로 효율적이지 않다는 것을 확인 할 수 있다. 다시
말해서 인덱스 DICT_VIEW_T1_IDX_01 이 훨씬 효율적이라는 것을 판단 할 수 있다.
그렇다면 실제로 그러한지 DATA 를 통해서 확인해 보도록 하자.
SELECT COUNT( * ) TOTAL_ROWS,
COUNT( DISTINCT c1 ) COL_NDV --- 인덱스 DICT_VIEW_T1_IDX_01 의 구성 칼럼
FROM dict_view_t1
TOTAL_ROWS COL_NDV
---------- -------
1000000 1000000
DICT_VIEW_T1_IDX_01 활용 시 실제 DATA 를 살펴보면 TABLE 총 ROW 수 1000000, 인덱
스 구성 칼럼 C1 의 DISTINCT 값 1000000 이므로 C1 조건으로 검색할 경우 인덱스를 통한 평
균 추출 건수가 1 건 일 것으로 예측 할 수 있으며 Dictionary View 를 통해서 살펴본 것과 동일
결과를 나타내는 것을 살펴 볼 수 있다.
SELECT COUNT( * ) TOTAL_ROWS,
COUNT( DISTINCT c2||c3||c4||c5 ) COL_NDV --- 인덱스 DICT_VIEW_T1_IDX_02 의 구성 칼럼
FROM dict_view_t1
TOTAL_ROWS COL_NDV
---------- -------
1000000 10
DICT_VIEW_T1_IDX_02 활용 시 실제 DATA 를 살펴보면 TABLE 총 ROW 수 1000000, 인덱
스 구성 칼럼 C2, C3, C4, C5 의 DISTINCT 값이 10 이므로 C2, C3, C4, C5 조건으로 검색할
경우 인덱스를 통한 평균 추출 건수가 100000 건 예측 할 수 있으며 Dictionary View 를 통해
서 살펴본 것과 동일 결과를 나타내는 것을 살펴 볼 수 있다. 다시 말해 인덱스
DICT_VIEW_T1_IDX_01 활용 시 1 번의 TABLE RANDOM ACCESS,
5. Part 1 ORACLE │177
DICT_VIEW_T1_IDX_02 활용 시 최대 100000 번의 TABLE RANDOM ACCESS 가 발생 할
수 있으므로 DICT_VIEW_T1_IDX_01 가 훨씬 효율적이라고 판단 할 수 있다.
마지막으로 해당 인덱스를 활용하여 실제 실행계획을 살펴 보도록 하자.
SELECT c1 ,
c2 ,
c3 ,
c4 ,
c5 ,
c6
FROM dict_view_t1 t
WHERE c2 = 'B'
AND c3 = '11'
AND c4 = 'RED'
AND c5 = '1981'
AND c1 = 1
----------------------------------------------------------------------------------------
| Id | Operation | Name | A-Rows | A-Time | Buffers |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 |00:00:00.01 | 4 |
|* 1 | TABLE ACCESS BY INDEX ROWID| DICT_VIEW_T1 | 1 |00:00:00.01 | 4 |
|* 2 | INDEX RANGE SCAN |DICT_VIEW_T1_IDX_01 | 1 |00:00:00.01 | 3 |
----------------------------------------------------------------------------------------
인덱스 DICT_VIEW_T1_IDX_01 를 활용한 SQL 의 실행 계획이다. 인덱스를 통해 1 건을 추출
후 1 번의 TABLE RANDOM ACCESS 가 발생 하였으며 총 4 BLOCKS 를 READ 하였다. 인덱스
구성 칼럼 C1 이 UNIQUE 하므로 인덱스 BLOCK READS 량 또한 매우 적은 것을 알 수 있다.
SELECT c1 ,
c2 ,
c3 ,
c4 ,
c5 ,
c6
FROM dict_view_t1 t
WHERE c2 = 'B'
AND c3 = '11'
AND c4 = 'RED'
AND c5 = '1981'
AND c1 = 1
6. 178│2013 기술백서 White Paper
----------------------------------------------------------------------------------------
| Id | Operation | Name | A-Rows | A-Time | Buffers |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 |00:00:00.09 | 3715 |
|* 1 | TABLE ACCESS BY INDEX ROWID| DICT_VIEW_T1 | 1 |00:00:00.09 | 3715 |
|* 2 | INDEX RANGE SCAN | DICT_VIEW_T1_IDX_02 | 100K |00:00:00.89 | 338|
----------------------------------------------------------------------------------------
CLUSTERING FACTOR 가 33770 이므로 약 30 ROW 당 1 TABLE RANDOM ACCESS 이므로 BLOCK
READS 량 감소
인덱스 DICT_VIEW_T1_IDX_02 를 활용한 SQL 의 실행 계획이다. 인덱스를 통해 100000 건
을 추출 후 약 3715-338 = 3377 번의 TABLE RANDOM ACCESS 가 발생 하였으며 총 3715
BLOCK READS 가 발생하였으며 인덱스 BLOCK READS 량 또한 DICT_VIEW_T1_IDX_01 에
비해서 비효율 적인 것을 알 수 있다.
총 3 가지의 SQL 실행 계획을 정리해 보면, 첫 번째 TABLE FULL SCAN 하였을 경우 총 3348
BLOCK, 두 번째 인덱스 DICT_VIEW_T1_IDX_01 를 활용 하였을 경우 인덱스 3 BLOCK
READS 그리고 1 번의 TABLE RANDOM ACCESS, 세 번째 DICT_VIEW_T1_IDX_02 를 활용
하였을 경우 인덱스 338 BLOCK READS 와 약 3377 번의 TABLE RANDOM ACCESS 가 발생
하고 있다. 즉 Dictionary View 를 통해 살펴 본 결과와 동일하게 인덱스
DICT_VIEW_T1_IDX_01 를 활용 했을 때 가장 효율적이라는 것을 실제 실행계획을 통해서 확
인 할 수 있다.
테이블, 인덱스 Dictionary View 상세 설명 및 활용 스크립트
위의 개선 사례로 보았듯이 Dictionary View에는 SQL성능을 개선하기 위한 판단 자료로 유용
한 View들이 존재 한다. DBA_TABLES, DBA_TAB_COLUMNS, DBA_INDEXES,
DBA_IND_COLUMNS, DBA_IND_EXPRESSIONS 등을 활용하여 성능 개선에 유용하게
사용될 수 있다.
Note. 문서에서 기술될 Dictionary View 의 버전은 11g R2 버전이다.
7. Part 1 ORACLE │179
TABLE, INDEX 관련 DBA_* VIEW
SQL 성능 이슈에 도움이 되는 TABLE, INDEX 관련 Dictionary View 인 DBA_TABLES,
DBA_TAB_COLUMNS, DBA_INDEXES, DBA_IND_COLUMNS, DBA_IND_EXPRESSIONS
에 관하여 자세히 알아보도록 하자.
DB A_TABLES
DBA_TABLES 는 데이터베이스에 있는 모든 TABLE 에 관한 정보들을 설명한 VIEW 다. 이
View 의 중요 컬러 정보는[표 1]와 같다.
Column Name Data Type Descrption
OWNER VARCHAR2(30) TABLE 의 OWNER
TABLE_NAME VARCHAR2(30) TABLE 의 이름
TABLESPACE_NAME VARCHAR2(30) TABLE 이 속해 있는 TABLESAPCE 명
PCT_FREE NUMBER 블록의 최소 여유 공간 (백분율)
PCT_USED NUMBER
블록에 대해 유지하려는 사용 공간의 최소 치(백
분율)
NEXT_EXTENT NUMBER 다음 extent 의 Size
MIN_EXTENTS NUMBER 세그먼트에 허용 된 extents 의 최소 수
NUM_ROWS* NUMBER TABLE ROW 수
BLOCKS* NUMBER TABLE 에 사용 된 DATA BLOCK 수
DEGREE NUMBER TABLE 을 병렬 처리 시 사용되는 Process 수
PARTITIONED VARCHAR2 파티션 TABLE 인지를 나타낸다.
LAST_ANALYZED DATE 마지막 통계정보가 생성된 날짜
AVG_SPACE NUMBER DATA BLOCK 의 평균 Free Space
AVG_ROW_LEN NUMBER TABLE ROW 의 평균 길이(In Bytes)
EMPTY_BLOCKS NUMBER TABLE 에 비어있는 BLOCK 수
[표 1] DBA_TABLES 중요 칼럼
Script 1>
SELECT table_name||'(' ||owner||')' || CHR( 10 ) ||tablespace_name
||decode( partitioned , 'YES' , '* Partitioned ' , '' )
||decode( TEMPORARY , 'Y' , '* Temporary ' , '' ) AS "TAB_INFO" ,
TRUNC( num_rows ) num_rows ,
8. 180│2013 기술백서 White Paper
avg_row_len ,
blocks || CHR( 10 ) || empty_blocks AS "BLK_INFO" ,
TRIM( degree ) degree ,
avg_space ,
chain_cnt ,
pct_free || '/' || pct_used || '/' || pct_increase pct ,
ini_trans || '/' ||max_trans tran ,
decode( SIGN( FLOOR( initial_extent/1024/1024 ) ) , 1 ,
ROUND( initial_extent/1024/1024 )
||'m' , ROUND( initial_extent/1024 ) ||'k' ) || '/'
|| decode( SIGN( FLOOR( next_extent/1024/1024 ) ) , 1 ,
ROUND( next_extent/1024/1024 )
||'m' , ROUND( next_extent/1024 ) ||'k' ) || CHR( 10 ) || min_extents ||'/'
|| decode( max_extents , 2147483645 , 'Unlimit' , max_extents ) inext ,
FREELISTS || '/' || freelist_groups free ,
TO_CHAR( last_analyzed , 'yyyy-mm-dd:hh24:mi:ss' ) last_analFROM dba_tables
WHERE table_name = UPPER( TRIM( :table_name ) )
AND owner = UPPER( TRIM( :schname ) )
[Scrpit 1] DBA_TABLES 활용
DBA_TAB_COLUMNS
DBA_TAB_COLUMNS 는 데이터베이스에 있는 Clusters, Tables, Views 의 모든 칼럼 정보들
을 담고 있다. 이 View 의 중요 칼럼 정보는 [표 2]와 같다.
Column Name Data Type Descrption
OWNER VARCHAR2(30) TABLE, VIEW, CLUSTER 의 OWNER
TABLE_NAME VARCHAR2(30) TABLE, VIEW, CLUSTER 의 이름
COLUMN_NAME VARCHAR2(30) COLUMN 의 이름
DATA_TYPE VARCHAR2(106) COLUMN 의 DATA TYPE
DATA_LENGTH NUMBER COLUMN 의 길이(In bytes)
NULLABLE VARCHAR2(1) NULL 사용가능 여부
NUM_DISTINCT NUMBER
COLUMN 의 DISTINCT 값(DATA VALUE 의 종류
수)
DENSITY NUMBER COLUMN 의 DENSITY 값
NUM_NULLS NUMBER COLUMN 에 포함 된 NULL 의 수
SAMPLE_SIZE NUMBER 통계정보 수집 시 사용되는 SAMPLE SIZE
LAST_ANALYZED DATE 마지막 통계정보가 생성된 날짜
9. Part 1 ORACLE │181
HISTOGRAM VARCHAR2
히스토그램의 TYPE(NONE, FREQUENCY, HEIFHT
BALANCED)
[표 2] DBA_TAB_COLUMNS 중요 칼럼
Script 2 >
SELECT column_name ,
data_type ,
data_length ,
decode( data_precision || '/' || data_scale , '/' ,
NULL , data_precision || '/' || data_scale ) dpds ,
nullable nn ,
num_distinct ,
density ,
num_nulls ,
num_buckets ,
sample_size ,
TO_CHAR( last_analyzed , 'yyyy-mm-dd' ) last_anal
FROM dba_tab_columns
WHERE owner = UPPER( TRIM( :schname ) )
AND table_name = UPPER( TRIM( :table_name ) )
[Scrpit 2] DBA_TAB_COLUMNS 활용
DBA_INDEXES
DBA_INDEXES 는 데이터베이스에 존재하는 모든 인덱스 정보를 담고 있다. 이 View 의 중요
칼럼 정보는 [표 3]와 같다.
Column Name Data Type Descrption
OWNER VARCHAR2(30) INDEX 의 OWNER
INDEX_NAME VARCHAR2(30 INDEX 의 NAME
INDEX_TYPE VARCHAR2(27)
INDEX 의 TYPE (NORMAL, BITMAP, FUNCTION-
BASED NORMAL 등)
TABLE_OWNER VARCHAR2(30) INDEX 를 소유하고 있는 TABLE 의 OWNER
TABLE_NAME VARCHAR2(30) INDEX 를 소유하고 있는 TABLE 의 이름
TABLE_TYPE CHAR(5)
INDEX OBJECT 의 TYPE (NEXT OBJECT, INDEX,
TABLE 등)
UNIQUENESS VARCHAR2(9) INDEX 가 UNIQUE OR NONUNIQUE 인지 식별
TABLESPACE_NAME VARCHAR2(30) INDEX 가 포함된 TABLE SPACE 이름
10. 182│2013 기술백서 White Paper
BLEVEL* NUMBER B-TREE 레벨 값
LEAF_BLOCKS* NUMBER INDEX 의 LEAF BLOCK 의 수
DISTINCT_KEYS* NUMBER INDEX 의 DISTINCT 값
PARTITIONED VARCHAR2(3) INDEX 의 파티션 유무
CLUSTERING_FACTOR NUMBER
DATA 가 INDEX ORDER 순으로 모여있는 정도를
나타냄
NUM_ROW NUMBER INDEX 의 총 ROW 수
LAST_ANALYZED DATE 마지막 통계정보가 생성된 날짜
[표 3] DBA_INDEXES 중요 칼럼
Script 3 >
SELECT index_name||'(' ||owner||')' index_name ,
SUBSTR( uniqueness , 1 , 1 ) u ,
tablespace_name||decode( partitioned , 'YES' , '*Partitioned ' , '' )
||decode( TEMPORARY , 'Y' , '*Temporary ' , '' ) TABLESPACE ,
TO_CHAR( TRUNC( num_rows ) ) ||chr( 10 ) ||to_char( distinct_keys ) AS
"NUM_ROWS_DISTINCT" ,
clustering_factor ,
leaf_blocks || CHR( 10 ) || blevel AS "BLK_INFO" ,
avg_leaf_blocks_per_key || '/' ||avg_data_blocks_per_key alb_adb ,
ini_trans || '/' ||max_trans tran ,
decode( SIGN( FLOOR( initial_extent/1024/1024 ) ) , 1 ,
ROUND( initial_extent/1024/1024 )
||'m' , ROUND( initial_extent/1024 ) ||'k' ) || '/' ||
decode( SIGN( FLOOR( next_extent/1024/1024 ) ) ,
1 , ROUND( next_extent/1024/1024 ) ||'m' , ROUND( next_extent/1024 ) ||'k' ) ||
CHR( 10 )
|| min_extents ||'/' || decode( max_extents , 2147483645 , 'unlimit' ,
max_extents ) inext ,
FREELISTS || '/' || freelist_groups free ,
TO_CHAR( last_analyzed , 'yyyy-mm-dd' ) last_anal
FROM dba_indexes
WHERE table_name = UPPER( TRIM( :table_name ) )
AND table_owner = UPPER( TRIM( :schname ) )
[Scrpit 3] DBA_INDEXES 활용
11. Part 1 ORACLE │183
DBA_IND_COLUMNS
DBA_IND_COLUMNS 는 데이터베이스에 있는 Clusters, Tables, Views 의 모든 인덱스 칼럼
정보들을 담고 있다. 이 View 의 중요 칼럼 정보는 [표 4]와 같다
Column Name Data Type Descrption
OWNER VARCHAR2(30) INDEX 의 OWNER
INDEX_NAME VARCHAR2(30 INDEX 의 NAME
INDEX_TYPE VARCHAR2(27)
INDEX 의 TYPE (NORMAL, BITMAP, FUNCTION-
BASED NORMAL 등)
TABLE_OWNER VARCHAR2(30) INDEX OBJECT 의 소유자(OWNER)
COLUMN_POSITION NUMBER INDEX 구성 COLUMN 의 순서
DESCEND VARCHAR2 SORT 상태를 나타냄
[표 4] DBA_IND_COLUMNS 중요 칼럼
Script 4 >
SELECT index_name ,
SUBSTR( index_type , 1 , 4 ) TYPE ,
SUBSTR( uniqueness , 1 , 1 ) u ,
(
SELECT MAX( decode( column_position , 1 , column_name ) ) ||
decode( MAX( decode( column_position , 2 , column_name ) ) , NULL ,
NULL , ', ' ) ||
MAX( decode( column_position , 2 , column_name ) ) ||
decode( MAX( decode( column_position , 3 , column_name ) ) , NULL ,
NULL , ', ' ) ||
MAX( decode( column_position , 3 , column_name ) ) ||
decode( MAX( decode( column_position , 4 , column_name ) ) , NULL ,
NULL , ', ' ) ||
MAX( decode( column_position , 4 , column_name ) ) ||
decode( MAX( decode( column_position , 5 , column_name ) ) , NULL ,
NULL , ', ' ) ||
MAX( decode( column_position , 5 , column_name ) ) ||
decode( MAX( decode( column_position , 6 , column_name ) ) , NULL ,
NULL , ', ' ) ||
MAX( decode( column_position , 6 , column_name ) ) ||
decode( MAX( decode( column_position , 7 , column_name ) ) , NULL ,
NULL , ', ' ) ||
MAX( decode( column_position , 7 , column_name ) ) ||
decode( MAX( decode( column_position , 8 , column_name ) ) , NULL ,
13. Part 1 ORACLE │185
Column Name Data Type Descrption
INDEX_OWNER VARCHAR2(30) INDEX 의 OWNER
INDEX_NAME VARCHAR2(30 INDEX 의 NAME
TABLE_OWNER VARCHAR2(30) INDEX 를 소유하고 있는 TABLE 의 OWNER
TABLE_NAME VARCHAR2(30) INDEX OBJECT 의 NAME
COLUMN_EXPRESSION LONG
FUNCTION-BASED INDEX COLUMN 의 표현 식
을 나타낸다.
COLUMN_POSITION NUMBER INDEX 구성 COLUMN 순서
[표 5] DBA_IND_EXPRESSIONS 중요 칼럼
결론
이번 기술 백서에서는 DBA_TABLES, DBA_TAB_COLUMNS, DBA_INDEXES,
DBA_IND_COLUMNS 의 간단한 활용 사례와 각각의 구성 칼럼들에 대하여 알아 보았다. 이처
럼 오라클은 성능 이슈에 활용 할 수 있는 다양한 Dicationary View 들을 제공해 오고 있다. 각
각의 View 들이 갖고 있는 정보들을 숙지하고 활용 한다면 SQL 성능 개선의 판단 자료로 활용
할 수 있을 것이다.