안녕하세요.

오늘은 데이터베이스 인덱스 개념에 대해 설명합니다.

인덱스란

인덱스(INDEX)DBMS의 검색 속도를 높이기 위한 기술 입니다.

DBMS는 데이터를 순차적으로 쌓으므로, 특정 데이터를 찾기 위해서는 데이터의 FULL-SCAN인 순차 탐색(O(N))이 필요합니다.

DBMS는 특정 데이터를 특별한 자료 구조로 쌓아 탐색 속도를 개선할 수 있는 기능을 제공합니다. 해당 기능을 인덱스라 부르고 쌓은 데이터들을 인덱스 테이블이라 부릅니다.

인덱스는 책의 목차와 비유할 수 있습니다. 우리가 책의 목차를 참고하여 필요한 내용으로 곧 바로 넘어가드시, DBMS인덱스 테이블에서 특정 인덱스를 찾아 필요한 행 데이터를 바로 가져옵니다.


인덱스 테이블

인덱스 테이블은 데이터를 조회할 때 사용되는 특정 컬럼의 데이터로 구성됩니다.

인덱스 테이블 에 포함된 데이터를 WHERE 문으로 조회를 하면 인덱스 테이블을 통해 ROW-ID를 빠르게 구한 뒤 단번에 행 데이터를 조회 할 수 있습니다.

인덱스 테이블 탐색

인덱스 테이블의 핵심은 빠른 조회 성능입니다. 이를 위해 인덱스 테이블은 탐색 트리 자료구조 중 하나인 B+트리 자료구조로 데이터를 저장합니다. 탐색 트리는 O(log2Nlog_2N) 성능의 빠른 조회를 할 수 있는 특징이 있습니다.

그렇기에, 데이터 FULL-SCAN[O(N)]성능에 비해, 압도적인 빠른 조회를 할 수 있는 장점 이 있습니다.

B+트리 포스팅을 참고해주세요.

인덱스 테이블 생성

TABLE을 생성 할 때, PRIMARY_KEY를 지정한 컬럼은 자동적으로 PRIMARY_KEY를 기준으로 인덱스 테이블이 생성됩니다.

만약 다른 컬럼을 인덱스 테이블을 생성하고 싶다면, 직접 생성해야 합니다.


인덱스 장점

인덱스의 장점은 곧 B+트리 자료구조의 장점과 일맥상통 합니다.

빠른 조회

인덱스 테이블은 메모리에 저장되어 있는 B+트리 자료구조 입니다.

메모리는 한정적인 자원이기 때문에 DBMS인덱스로 지정한 컬럼 데이터와 ROW-ID로 구성된 최소한의 노드로 B+트리를 구성합니다.

ROW-ID는 파일에 저장되어 있는 행 데이터를 가져올 수 있는 정보입니다.

여기에서 알 수 있는 재미있는 특징이 하나 있습니다. 데이터 FULL-SCAN이 느린이유는 순차탐색인 이유도 있지만, 빈번한 파일IO도 많은 영향을 미칩니다.

반면에 빠른 메모리 조회로 행 아이디를 찾는 인덱스 방식은 최소한의 파일IO를 사용합니다. 최소한의 파일IO는 더욱 빠른 탐색 속도를 가능하게 합니다.

데이터 정렬

만약 인덱스된 컬럼으로 정렬 명령을 내린다면 정렬 비용을 아낄 수 있습니다.

B+트리 구조상 조회된 데이터를 가져오기만 해도 정렬된 데이터를 획득할 수 있기 때문입니다.


인덱스 단점

지금까지의 설명만 보자면 인덱스 기능은 매우 훌륭한 기능 같습니다만, 그에 못지 않은 단점도 존재합니다. 대표적으로 아래와 같은 단점이 존재합니다.

  • 인덱스 테이블 유지 비용 (B+트리 유지비용)
  • 인덱스 테이블 추가 공간 비용

인덱스 테이블 유지 비용

B+트리의 중요한 특징 중 하나는 균형 이진 트리를 구성한다는 점 입니다. 노드의 삭제, 삽입시 트리 균형을 위해 트리 구조를 재구성 하는 비용이 발생합니다. 더군다나 탐색 이진 트리의 업데이트는 삭제 + 삽입 과정이 발생하므로 2배의 비용이 발생하게 됩니다.

위에서 살펴본 B+트리의 특징이 인덱스 테이블에도 똑같이 적용됩니다.

즉, O(log2Nlog_2N)으로 빠르게 조회가 가능하지만 삽입, 삭제, 업데이트 작업은 노드의 위치 탐색 비용 + 트리 재구성 비용 이 발생하게 됩니다.

DBMS는 트리 재구성 비용이라도 아끼기 위해 노드 삭제를 진행하지 않습니다. 대신 해당 노드에 사용하지 않는다는 마킹만 진행합니다. 그로인해 DBMS의 삭제, 업데이트 명령은 노드의 위치 탐색 비용만 발생하게 됩니다.

인덱스 테이블 추가 공간 비용

인덱스 테이블의 노드 삭제를 하지 않음으로써, 트리 재구성 비용을 아낀 전략은 유효해 보입니다. 하지만 이 역시도 다른 문제가 존재합니다.

그 문제는 바로, 인덱스 테이블이 거대해짐에 따라, 트리의 높이가 깊어지는 문제 입니다.

이는 테이블의 행 개수 보다 많은 개수의 저장공간을 필요로 합니다.

하지만 더욱 결정적인 문제는 트리 높이에 따른 성능으로 인해 인덱스 테이블 의 깊은 높이는 DBMS 성능을 점진적으로 내린다는 점 입니다.

결론적으로, 미 사용 노드를 트리에서 제거함으로써 높이 최적화가 필요함 을 알 수 있습니다. DBMS는 트리 높이 최적화를 수행하는 명령을 제공합니다. 해당 명령을 주기적으로 수행함으로써 전체적인 DBMS 성능을 높일 수 있습니다.


인덱스 생성 전략

위에서 살펴본 인덱스의 단점을 통해, 다음과 같은 결론을 도출 할 수 있습니다.

조회보다 삽입, 삭제, 업데이트가 더 많이 발생하는 테이블은 인덱스 기능이 오히려 단점이 될 수 있습니다.

또한 인덱스를 설정할 때는 유의할점이 몇개 존재합니다.

Cardinality 체크

인덱스를 구성할 땐, 컬럼의 Cardinality 를 고려하여 생성해야 합니다.

Cardinality 란 값의 분산도를 의미합니다. 다르게 표현하자면 값이 형태가 얼마나 다양하게 나올 수 있느냐의 척도입니다. 만약 (Y, N) 2가지 값으로만 구성된 컬럼을 인덱스로 설정하는 것은, 1700 페이지로 구성된 책에 목차가 2개만 존재하는것과 마찬가지 효과 입니다.

그렇기에 행 데이터가 최대한 많이 분류될 수 있는 컬럼으로 인덱스를 생성해야 효과적입니다.

조회 조건 빈번도 체크

당연한 얘기일 수 있겠지만, 조회 조건으로 자주 사용되는 컬럼일수록 인덱스 조건에 부합합니다.

아래의 항목은 간단한게 체크해볼 수 있는 리스트 입니다.

  • 조건절에 자주 등장하는 컬럼
  • LIKE 검색보다는 = 으로 검색하는 컬럼
  • ORDER BY 절에서 자주 사용되는 컬럼
  • JOIN으로 자주 사용되는 컬럼


지금까지 살펴본 내용을 요약하자면 다음과 같습니다.

  • 인덱스B+트리 구조를 통해 조회 성능을 올리는 기능입니다.
  • 데이터 FULL-SCAN은 빈번한 파일IO 작업을 통한 순차탐색으로 매우 느린 반면에 인덱스는 메모리에 저장된 트리 탐색을 통해 파일의 위치를 획득하여 파일IO 작업을 최소화 합니다.
  • 인덱스는 조회 성능을 높이고 삽입, 삭제, 업데이트 성능을 낮추는 트레이드 오프 기능 이므로 조회가 주된 목적인 테이블일 수록 유리합니다.
  • 인덱스는 조회가 주된 목적인 테이블일 수록 유리합니다.
  • 인덱스 테이블의 높이는 점점 깊어지므로, 주기적인 정리가 필요합니다.
  • 인덱스를 생성할 때는 Cardinality조회 조건 빈번도 체크가 필요합니다.

오늘 포스팅은 여기까지 입니다.

읽어주셔서 감사합니다.

'데이터베이스' 카테고리의 다른 글

[MySQL] 데이터베이스 원격 접속 명령어  (0) 2020.08.21
트랜잭션(Transaction)이란?  (26) 2017.02.27
Mysql 외부접근 설정하기.  (0) 2015.11.16

포스팅이 도움 되셨다면, 커피 한잔 후원해주세요!
더 좋은 포스팅 작성에 큰 힘이 됩니다.

Buy me a coffeeBuy me a coffee


오늘 포스팅 할 내용은 IntelliJ IDEA 의 내장된 DB Client를 사용하는 방법에 대해 기술합니다.

사용한 환경은 대략적으로 아래와 같습니다.

  • Mac OS

  • IntelliJ IDEA Ultimate

  • H2 데이터베이스

  • Maven Project

H2 데이터베이스 실행하기

http://www.h2database.com/html/download.html

위 경로에서 H2 데이터베이스를 설치합니다.

다운받은 후, bin 경로의 h2.sh 스크립트를 실행합니다. (윈도우 사용자라면, h2.bat 을 실행하면 됩니다.)

실행하면, 아래 이미지와 같이 기본 설정된 브라우저로 데이터베이스 접속화면이 뜹니다.

Note. 브라우저의 접속화면이 계속 로딩 화면으로 유지 된다면, url을 localhost 로 변경 해보세요.

화면 상단 언어설정에서 한국어로 바꾼후,

위 이미지 처럼 설정 하되, 세부 설정은 아래의 설명을 참고해주세요.

JDBC URL 맨 끝에는 원하시는 데이터베이스 명을 넣으시면 됩니다.

ex) Database 이름을 Person으로 -> jdbc:h2:tcp://localhost/~/Person

사용자명비밀번호 는 개인적으로 맘에드는 것을 작성하면 되지만, 기억하셔야 합니다.

저는 사용자명sa비밀번호는 작성하지 않았습니다.

설정이 끝난 후 연결시험을 눌러 시험 성공 메시지가 뜨는지 확인해주세요.

성공 메시지가 정상적으로 떴다면, 연결 버튼을 눌러 연결을 해주세요.

의존성 준비하기 (FEAT. MAVEN)

필요한 의존성은 H2 Database 프로그램을 Java 프로젝트와 연동할 H2 Database Driver 라이브러리가 필요합니다.

pom.xml 의 dependency 설정부분에 아래와 같이 의존성을 추가해주세요.

<dependency>
 <groupId>com.h2database</groupId>
 <artifactId>h2</artifactId>
 <version>1.4.193</version>
</dependency>

INTELLIJ DB CLIENT 연결하기.

Action 검색으로 Database를 검색합니다. ( shift + shift )

Database 탭이 뜬 후, + 버튼을 눌러 DataSource > H2 를 누릅니다.

설정창이 뜰텐데요, 정보를 기입할때 몇가지 유념해야할 사항이 있습니다.

Connection Type

저희는 H2 Database 프로그램을 서버모드로 작동시켰습니다.

http://www.h2database.com/html/features.html#database_url

대응하는 Type은 Remote 입니다. 해당 Type을 선택해줍니다.

Driver

Maven으로 H2 Database Driver 모듈을 다운받았다면,

H2 로 설정되어 있습니다. 만약 안되어 있다면, 의존성을 다시 확인해주시고, 수동 설정을 해보시길 바랍니다.

Host

H2 Database 가 실행된곳의 서버정보를 입력하면 됩니다. (보통 localhost)

Port

port 는 조금 알아야하는 내용이 있습니다.

기입해야할 port H2 Database 웹 브라우저 접속에서 사용한 8082번 포트가 아닙니다.

8082 번 포트는 H2 Database의 웹 어플리케이션을 구동할때 사용하는 포트번호 입니다.

우리가 실제로 연결해야할 H2 Database의 프로그램 포트번호는 9092 번을 사용합니다.

따라서, 9092 번으로 기입합니다.

User , Password

H2 Database 웹 접속화면에서 작성한 아이디와 비밀번호를 입력하면 됩니다.

Database

우리가 작성한 JDBC URL 포맷은 ~ 를 사용하여 상대경로로 표현했습니다.

아쉽게도 IntelliJ IDEA 가 해당 표현을 인지를 못하는거 같아, 일단 공백으로 둡니다.

아래의 URL을 작성하는 곳에서 Database 명까지 한번에 입력할 예정입니다.

URL

지금 까지 설정대로 잘 작성했다면, 아래와 같은 패턴으로 자동완성되어 있습니다.

jdbc:h2:tcp://{host}:9092/

우리가 사용한 URL 포맷으로 아래와 같이 바꿉니다. (데이터베이스 명까지 한번에 작성합니다.)

jdbc:h2:tcp://{host}:9092/~/{데이터베이스 명}

마지막으로 TEST CONNECTION 버튼으로 연결 테스팅을 진행 후, 설정을 마칩니다.

마무리

IntelliJ IDEADatabase 탭 메뉴중 콘솔을 눌러서 잘되었는지 간단한 명령어로 확인해봅니다.

ex) show tables;

만약 스키마 목록이 보이지 않는다면, Database 탭 메인 화면에서 오른쪽에 조그만한 숫자를 눌러, 메뉴 표시를 하시면 됩니다.

오늘 포스팅은 여기까지 입니다.

읽어주셔서 감사합니다.

'IDE' 카테고리의 다른 글

[IntelliJ] 인텔리J에 이클립스 Tab 기능 설정하기.  (2) 2018.12.23
[Eclipse] 이클립스 폰트 설정  (0) 2016.04.08

포스팅이 도움 되셨다면, 커피 한잔 후원해주세요!
더 좋은 포스팅 작성에 큰 힘이 됩니다.

Buy me a coffeeBuy me a coffee

+ Recent posts