태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

[Oracle is Mad] Index Rebuild를 둘러싼 논쟁 - Part2

오라클 2007.12.24 22:38
Index Rebuild는 Oracle과 관련된 논쟁들중에서 가장 뜨거운 쟁점에 속한다.
이 논쟁을 이해하기 위해서 필요한 몇가지 지식을 정리해보자.

우리가 흔히 사용하는 B*Tree Index는 다음과 같은 속성을 지닌다.
  • B*Tree에서 "B"는 Balanced의 약자이다.
  • B*Tree Index는 Root->Branch->Leaf의 Tree 구조를 가지며, Tree 높이는 키의 수에 따라 결정된다.
  • Balanced란 Index 키 값에 무관하게 Root Node에서 Leaf Node로 가는 경로의 길이가 일정하다는 의미이다.
  • B*Tree Index는 상당히 효율적이어서 대부분의 대용량 데이터에서도 Root Node에서 Leaf Node까지의 탐색 길이가 3~4 블록 정도에 불과하다. 이 말은 특정 키 값을 검색하는데 불과 3~4 블록 정도의 Logical Reads만이 필요하다는 의미이다.
  • Leaf Node는 정렬된 상태로 연결되어 있다. 따라서 Leaf Node에서 하나의 키 값을 찾으면 정렬된 형태로 다음 키 값을 매우 손쉽게(Leaf Node만 따라가면 되므로) 얻을 수 있다.
B*Tree Index를 그림으로 표현하면 아래 그림과 같다.
사용자 삽입 이미지

여기까지는 너무나 상식적인 내용이므로 별도의 설명은 사족에 불과하다.

여기서의 핵심은 B*Tree Index는 매우 효과적인 탐색 구조를 가지고 있으며, 키 값 탐색에 매우 적은 량의 Logical Reads만이 필요하다는 것이다.

그럼에도 불구하고 왜 많은 사람들이 Index를 Rebuild하라고 권고하고, 또 많은 시스템에서 실제로 Index Rebuild를 수행하는가? 그 이유는 매우 많다.

하지만, 일차적으로 다음과 같은 잘못된 지식이 Index Rebuild를 부추기는 원인을 제공했다.

"Index에서 삭제된 Entry(키 값)나 Block은 재사용되지 않는다"

위와 같은 잘못된 지식들이 어떤 알 수 없는 이유로(아마 외국에서 발행된 책이나 자료 등에서...) 몇 몇 엔지니어사이에서 회자되었고 그 결과로 상당히 넓은 범위로 이런 지식들이 보급된 것으로 생각된다.

위의 잘못된 사실을 연쇄적으로 다음과 같은 오해를 불러일으킨다.
  • 이전 값이 계속해서 삭제되고, 새로운 값이 계속해서 추가되는 환경을 생각해보자.
  • 삭제된 Entry나 Block은 재사용되지 않으므로 Index의 크기는 계속적으로 증가할 것이다.
  • Index의 크기가 늘어남으로써 Logical Reads가 증가하고 공간 요구량은 터무니없이 증가할 것이다.
생각만 해도 끔찍하지 않은가? 이렇게 생각한다면 누구라도 alter index ... rebuild 명령문을 당장 실행하고 싶어질 것이다.

하지만 다행히 위의 지식은 완전히 잘못된 것이다. 실제로는 다음과 같이 말해야 정확한 것이다.

- Deleted Entries는 다음번 Insertion시에 정리된다.
가령 특정 Leaf Node Block에 (1,2,3,4,5) Entry가 있다. 한 세션이 2를 삭제하고 Commit하면 (1,-,3,4,5)가 된다. 다른 세션이 여기에 6을 Insertion하면? (1,-,3,4,5,6)이 아니라 (1,3,4,5,6)과 같이 삭제된 Entry가 정리된다.

- Deleted Block은 New Block이 필요할 때 재활용된다.
Deleted Block은 현재 모든 Entry가 삭제된 Block을 말한다. 이런 Block들은 Leaf Node에 텅 빈 채로 남아 있다가 새로운 Leaf Node나 Branch Node가 필요할 때(New Block) 재활용된다.

아래 URL에 위의 사실을 증명하는 간단한 Case Study가 있다.

http://wiki.ex-em.com/index.php/Oracle_is_mad#Script_.28Index_Space_Reuse.29

Index에서 삭제된 Entry나 Block은 재사용되지 않는다는 것은 완전히 잘못된 것이다. 따라서 이러한 잘못된 믿음이 Index Rebuild를 수행하는 근거가 되어서는 안된다.

오히려 다음과 같은 사실을 걱정해야 한다.
  • 삭제된 Entry는 해당 Leaf Node에 새로운 Insertion이 발생하지 않으면 삭제된 상태로 남아 있다.
  • 텅빈 Block은 새로운 Block 요청에 의해 재사용되기 전까지는 그대로 남아 있다.
즉, 삭제된 Entry나 Block들은 Index Tree 구조에 그대로 남아 있다. 이것은 너무나 당연한 결과이지만, 이로 인해 Index Scan 성능이 떨어질 수 있다. 여기서 오는 공포심(?)이 Index Rebuild를 조장하는 가장 중요한 원인일 것이다. 다음 Part에서 이 문제를 다루기로 한다.


신고
Trackback 0 : Comments 4
  1. 이민규 2008.06.13 17:05 신고 Modify/Delete Reply

    질문 : Deleted Entries는 다음번 Insertion시에 정리된다. 라고 하셨는데요

    index 생성시 pctused의 개념이 없습니다. 그렇다면 어떤 index가 1~100의 값으로 차있는 상태에서
    50을 지우고 다시 50을 insert 하는 경우 원래 block에 들어 갈 수 있다는 말씀인가요?

    그렇다면 index rebuild를 왜 하는건가요? 즉 데이타의 증가가 없다면 split이 발생하지 않고 말씀 하신대로라면
    인덱스 rebuild가 필요 없다는 말씀인데요....설명 부탁드립니다.

  2. 이민규 2008.06.13 17:08 신고 Modify/Delete Reply

    Deleted Entries는 다음번 Insertion시에 정리된다.의 의미가 pctfree를 넘지 않은 블럭에만 해당되는것 아닌가요?

  3. 이민규 2008.06.13 19:28 신고 Modify/Delete Reply

    테스트 수행 결과 욱짜님 말씀이 맞습니다. 그동안 잘못 알고 있었습니다. ...감사합니다.

  4. 욱짜 2008.06.13 21:09 신고 Modify/Delete Reply

    http://ukja.tistory.com/138
    참조하세요.

Write a comment

티스토리 툴바