데이터베이스에서 데이터를 적재하는 객체는 테이블이다. 테이블들은 2차원으로 구성되어 있으며, 개발자나 DBA가 제일 많이 접하는 객체일 것이다. 하지만 테이블은 모두 똑같은 형태로 이뤄지는 것은 아니다.
테이블을 구성하는 물리적인 형태는 일반 테이블 세그먼트, 파티션 테이블 세그먼트, 클러스터 테이블 세그먼트 그리고 IOT(Index Organized Table) 세그먼트 등이 존재한다.
여기서 소개할 내용은 제일 많이 접하는 일반 테이블 세그먼트와 파티션 테이블 세그먼트를 제외하고, 많이 쓰이지 않는 IOT 테이블 세그먼트에 대해 이야기하고자 한다.
IOT 세그먼트는 Oracle 8i 때부터 지원되어 온 물리적 세그먼트 형태다. 소개하고자 하는 기술은 신기술이 아니라는 것이다.
많은 프로젝트를 경험한 베테랑에게 ""IOT를 사용해 성능 면에서 효과를 본 사례가 있습니까?""라고 질문하면, 10명 중 9명은 "IOT를 사용하는 프로젝트는 보지 못했다""라고 대답한다.
그렇다면 이 9명의 베테랑들이 경험한 프로젝트는 IOT라는 테이블 세그먼트 구조가 필요 없는 곳일까? 필요 없는 것이 아니라 굳이 IOT 세그먼트의 성능적인 이점이 없어도 성능에 아무런 이상이 없었기 때문이다.
하지만 성능 컨설팅을 거친 프로젝트에는 반드시 IOT 세그먼트 구성이 이뤄진다. 정확한 구조의 습득에 의한 장점과 단점을 파악한다면, 최고의 성능을 낼 수 있는 것이 IOT 세그먼트다.
우리가 사용하는 테이블은 자료를 저장하기 위한 매체로 이용되며, 여기에 빠른 조회속도를 내기 위해 인덱스를 이용하는 것이 일반적이다.
데이터를 적재하기 위해 테이블 구조를 만들고, 기본적인 조인과 조회의 속도를 위해 Primary Key 인덱스를 생성한다. 이제 IOT 세그먼트와 일반 테이블의 내부 실행 계획의 차이를 알아보자.
인덱스를 이용한 데이터의 조회는 인덱스를 액세스한 후 검색된 ROWID에 의해 테이블을 다시 액세스하는 반면, IOT를 이용한 조회는 해당 세그먼트의 액세스만으로 데이터를 추출하는 실행계획을 <리스트 2>와 같이 확인할 수 있다.
SELECT * FROM VOID_TEST A WHERE ID <= '00300'; Call Count CPU Time Elapsed Time Disk Query Current Rows ------- ----- -------- ------------ ---- ----- ------- ---- Parse 1 0.000 0.001 0 0 0 0 Execute 1 0.000 0.000 0 0 0 0 Fetch 4 0.000 0.001 0 104 0 300 ------- ----- -------- ------------ ---- ----- ------- ---- Total 6 0.000 0.002 0 104 0 300 Rows Row Source Operation ---- ------------------------------------------------- 0 STATEMENT 300 TABLE ACCESS BY INDEX ROWID VOID_TEST (cr=104 pr=0 pw=0 time=3347 us) 300 INDEX RANGE SCAN VOID_TEST_PK (cr=6 pr=0 pw=0 time=1822 us)
SELECT * FROM IOT_TEST A WHERE ID <= '00300'; Call Count CPU Time Elapsed Time Disk Query Current Rows ------- ----- -------- ------------ ---- ----- ------- ---- Parse 1 0.000 0.000 0 0 0 0 Execute 1 0.000 0.000 0 0 0 0 Fetch 4 0.000 0.001 0 10 0 300 ------- ----- -------- ------------ ---- ----- ------- ---- Total 6 0.000 0.001 0 10 0 300 Rows Row Source Operation ---- ------------------------------------------------- 0 STATEMENT 300 INDEX RANGE SCAN SYS_IOT_TOP_52546 (cr=10 pr=0 pw=0 time=1543 us
그럼 이 두 실행계획에 대해 자세히 분석해 보자.
첫째, ROWID를 이용한 테이블 액세스가 사라졌다. OLPT 환경에서 이뤄지는 작업들은 대부분 인덱스를 경유하며, ROWID를 이용한 액세스가 이뤄지는 것이 80% 이상이다. CPU의 부하가 제일 많은 곳 또한 그 부분이다.
일반 테이블에서 위 SQL의 결과를 얻기 위해 104블록을 사용했고, IOT 세그먼트는 일반테이블 세그먼트보다 10배 적은 10블록만 사용했다는 것이다. 동시에 접근하는 사용자가 많을수록 이 부분은 엄청난 성능 차이를 내게 된다.
둘째, 2개 모두 동일한 INDEX RANGE SCAN이지만, 읽은 블록수가 다르다. 일반 테이블에서는 6개 블록, IOT 테이블에서 는 10개의 블록을 사용했다.
이 부분은 IOT의 가장 큰 핵심적인 부분을 이야기하는 것이다. 즉, 일반 인덱스 세그먼트와 IOT 세그먼트의 차이점이다.
일반 인덱스 세그먼트는 해당 키와 ROWID만 가지고 있기 때문에 제한된 블록 속에 많은 ROW를 적재할 수 있지만, IOT 세그먼트는 해당 키와 그 외적인 칼럼의 정보까지 Leaf 블록에 저장하기에 하나의 블록에 많은 정보를 보유하지 못하는 것이다.
하지만 이렇게 많은 블록을 사용하는 것이 단점인 동시에 장점이 된다. 해당 정보를 동일 공간에 보유하고 있기 때문에 ROWID를 이용한 랜덤 액세스가 사라지게 되는 것이다.
B-Tree 인덱스 | IOT | |
---|---|---|
구성 | Index Key Value + Physical ROWID | Index Key Value + Non KEY VALUE + Logical ROWID |
ROWID | Physical ROWID | Logical ROWID |
칼럼타입 한계 | 없음 | Long, Long raw, LOB 지원 불가 |
PK 인덱스 | 생성(스토리지 중복사용) | IOT 자체가 PK 인덱스 역할 |
어떠한 물리적 구조나 데이터베이스 오브젝트도 모두 단점이 존재하며, 사용자는 오브젝트의 정확한 특성을 파악해 사용해야 최적의 데이터베이스를 구축할 수 있다.
IOT 세그먼트도 갖고 있는 장점에 비해 많은 단점이 존재한다. 적을 알고 나를 알면 백 전백승이라고 했다. 이제 우리는 IOT의 단점을 제대로 파악하고 효과적으로 IOT 세그먼트를 사용할 수 있도록 해야 한다.
첫째, IOT 또한 인덱스의 구조를 가지고 있다.
인덱스의 최고 단점이라고 한다면 정렬에 대한 부담일 것이다. 우리가 한 테이블에 많은 인덱스를 생성하면 DML의 성능이 느려지듯이, IOT 또한 PK 인덱스 순서를 유지하려고 많은 부하를 일으킨다.
그럼에도 우리가 인덱스를 계속 사용하고 있는 것은 빠른 조회속도로 인해 얻는 점이 잃는 것보다 많기 때문이다. IOT 세그먼트 또한 빠른 조회 속도와 정렬된 자료로 인한 이점을 잘 활용한다면, 이와 같은 부하는 적절히 안배해야 될 것이다.
둘째, 칼럼의 수와 사이즈를 최소화하라.
IOT 세그먼트의 구성은 키 인덱스 값과 그 외의 값으로 구성됨을 보았을 것이다. 칼럼의 수가 많아지고 사이즈가 크다면, 조회하는 시간 또한 길어져 적절하지 않은 구성이 된다.
그렇다면 이러한 상황의 테이블들은 어떠한 것이 있을까? 매핑 테이블이나 코드성 테이블, 메뉴테이블 등이 이에 속한다.
칼럼의 수가 많지 않고 DML의 횟수가 적지만, 전체 시스템 면에서 바라본다면 해당 테이블들의 조회는 시스템 부하의 반 이상을 차지할 것이다.
매핑 테이블의 경우는 M:M 테이블들이 조합되어 칼럼의 90%가 Primary Key로 구성되는 것이 대표적인 사례다.
이렇듯 테이블이 만들어지고, 90% 이상의 칼럼이 같은 Primary Key 인덱스를 만든다면 중복되는 데이터로 인한 비효율적인 스토리지 운영이 될 수 있다.
셋째, 사이즈가 큰 칼럼이 존재한다면 Overflow 영역을 활용하라.
두 번째에서 이야기했듯이 IOT 세그먼트 자체의 칼럼 크기는 매우 중요하다. 인덱스 키 외의 칼럼 중 자주 사용되지 않거나 칼럼의 크기가 커서 IOT의 성능을 저하시킬 수 있는 칼럼들이 있다면 과감히 Overflow 영역으로 지정하는 것이다.
Overflow 영역은 게시판 테이블에서 상세내용에 해당되는 큰 칼럼을 따로 저장하는 것과 유사하다. 테이블에 자주 쓰이지 않는 큰 칼럼들이 존재한다면, 1개의 블록에 저장하려는 ROW들이 줄어들 것이고, 이로 인해 조회 성능에 악영향을 미칠 것이다.
- 강좌 URL : http://www.gurubee.net/lecture/2640
- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.