Download - SQL 튜닝에 Dictionary View 활용하기 Part2_Wh oracle

Transcript

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'

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를 통해서 관련 정보를 얻을 수 있다.

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 =

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,

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

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버전이다.

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 ,

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 마지막 통계정보가 생성된 날짜

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 이름

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 활용

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 ,

184│2013 기술백서 White Paper

NULL , ', ' ) ||

MAX( decode( column_position , 8 , column_name ) ) ||

decode( MAX( decode( column_position , 9 , column_name ) ) , NULL ,

NULL , ', ' ) ||

MAX( decode( column_position , 9 , column_name ) ) ||

decode( MAX( decode( column_position , 10 , column_name ) ) , NULL ,

NULL , ', ' ) ||

MAX( decode( column_position , 10 , column_name ) ) ||

decode( MAX( decode( column_position , 11 , column_name ) ) , NULL ,

NULL , ', ' ) ||

MAX( decode( column_position , 11 , column_name ) ) ||

decode( MAX( decode( column_position , 12 , column_name ) ) , NULL ,

NULL , ', ' ) ||

MAX( decode( column_position , 12 , column_name ) ) ||

decode( MAX( decode( column_position , 13 , column_name ) ) , NULL ,

NULL , ', ' ) ||

MAX( decode( column_position , 13 , column_name ) ) ||

decode( MAX( decode( column_position , 14 , column_name ) ) , NULL ,

NULL , ', ' ) ||

MAX( decode( column_position , 14 , column_name ) ) ||

decode( MAX( decode( column_position , 15 , column_name ) ) , NULL ,

NULL , ', ' ) ||

MAX( decode( column_position , 15 , column_name ) )

FROM all_ind_columns col

WHERE col.index_name = a.index_name

AND col.table_owner = a.table_owner

AND col.table_name = a.table_name

) AS column_list

FROM dba_indexes a

WHERE a.table_name = UPPER( TRIM( :table_name ) )

AND a.table_owner= UPPER( TRIM( :schname ) )

ORDER BY index_name

[Scrpit 4] DBA_IND_COLUMNS 활용

DBA_IND_EXPRESSIONS

DBA_IND_EXPRESSIONS는 데이터베이스의 Clusters, Tables, Views있는 모든

FUNCTION-BASE 인덱스 관련 정보를 담고 있다. 이 View의 중요 칼럼 정보는 [표 5]와 같다

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 성능 개선의 판단 자료로 활용

할 수 있을 것이다.