DB

DB 인덱스 기초

정한_s 2023. 7. 14. 17:14

데이터베이스 인덱스는 데이터베이스 테이블의 데이터를 더 빠르게 검색하고 쿼리하는 데 사용되는 자료구조입니다. 책의 색인과 비슷합니다. 데이터베이스에서 특정 값을 찾고자 할 때, 테이블의 모든 행을 검사하지 않고 해당 값이 있는 행을 빠르게 찾을 수 있게 해줍니다.

인덱스를 사용하면 데이터 검색 속도가 빨라 지지만 테이블에 데이터를 삽입하거나, 업데이트 하는 작업은 더 오래 걸릴 수 있습니다. 왜냐하면 각 삽입이나 업데이트 시 변경에 대해서 인덱스 역시 업데이트를 해야 하기 때문입니다. 따라서, 성능 튜닝에 좋은 도구 이지만, 어떤 열에 인덱스를 생성할지, 어떤 타입의 인덱스를 사용할지 등은 확인후에 결정해야 합니다.

 

그렇다면 인덱스를 걸기에 효율적인 칼럼은 무엇일까요? 읽기 작업이 쓰기 작업에 비해 많고, 카티널리티가 높은 칼럼에 거는 것이 효율적입니다.

 

** 카디널리티란?

특정 컬럼이 고유한 수를 나타냅니다. 예를 들어, '성별'이라는 컬럼이 있다면 이 컬럼의 카디널리티는 '남성', '여성' 등의 고유한 값의 수를 의미합니다. 즉 중복되는 값이 적을 수록 카디널리티가 높고, 많을 수록 카디널리티는 낮습니다.

데이터 베이스의 여러 종류의 인덱스가 있습니다.

자료구조

B-Tree 인덱스: B-Tree 인덱스는 범용적으로 많이 사용됩니다. 이름이나 이메일과 같이 중복이 많을 수 있고 검색이 빈번하게 이루어지는 필드에 대해 B-Tree 인덱스를 사용하면 효율적일 수 있습니다. 특히, 부분적인 값으로 검색하거나 값의 범위를 지정한 쿼리에 유리합니다.
MySQL에서 인덱스를 생성 할 때, 기본적으로 B-Tree의 확장인 B+ 트리를 사용합니다

B+Tree 시뮬레이션
https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html 

 

Hash 인덱스: Hash 인덱스는 주로 '정확히 일치'하는 쿼리에 사용됩니다. 예를 들어, 사용자의 고유 ID와 같이 정확한 값으로 검색하는 경우에는 Hash 인덱스가 효과적일 수 있습니다. 하지만, 범위 검색이나 정렬된 데이터가 필요한 쿼리에는 부적합합니다.
MySQL에서 MEMORY 테이블 사용시 Default가 Hash 인덱스입니다.

  • 메모리 테이블이란?
    MEMORY 테이블은 매우 빠른 데이터 액세스를 제공하지만, 서버가 종료되면 모든 데이터가 사라지는 휘발성 테이블입니다.
    생성 방법 예시
    CREATE TABLE lookup (id INT, INDEX USING HASH (id)) ENGINE = MEMORY;

Bitmap 인덱스: Bitmap 인덱스는 카디널리티가 낮은 열에 적합합니다. 성별이나, 학년, 결혼 여부 등의 열에는 Bitmap 인덱스를 사용하면 좋습니다. 여기서 주의해야 할 점은 Bitmap 인덱스는 데이터가 자주 변경되는 환경에서는 성능이 떨어질 수 있다는 것입니다.
MySQL에서 Bitmap 인덱스를 지원하지는 않지만, 카디널리티가 낮은 경우 B-Tree 인덱스와 유사하게 작동합니다

 

유형

Clustered 인덱스:

클러스터형 인덱스는 데이터베이스 테이블에 대한 물리적인 정렬을 제공하는 인덱스입니다. Clustered 인덱스는 테이블의 물리적인 저장 순서를 결정하므로, 범위 검색이 빈번하게 일어나는 경우에 유리합니다. 예를 들어, 시간 순서대로 로그 데이터를 검색하는 경우 Clustered 인덱스를 사용하면 빠른 검색 속도를 보장받을 수 있습니다.
MySQL에서는 기본 키(Primary Key)가 클러스터 인덱스로 자동 생성됩니다. 따라서, 기본 키를 생성하는 것으로 클러스터 인덱스를 생성할 수 있습니다

 

Non-Clustered 인덱스

비클러스터형 인덱스는 데이터베이스 테이블의 레코드를 물리적으로 정렬하지 않고, 별도의 구조로 인덱스를 생성합니다. 테이블의 데이터 자체를 재정렬하지 않기 때문에, 데이터 변경 작업이 빈번하게 일어나는 경우에도 성능 저하를 최소화할 수 있습니다. 예를 들어, 고객의 이름이나 주소와 같은 열에 Non-Clustered 인덱스를 생성할 수 있습니다.
MySQL에서는 기본적으로 모든 보조 인덱스(Primary Key가 아닌 인덱스)가 Non-Clustered 인덱스입니다. 따라서, 다음과 같이 B-Tree 인덱스를 생성하면 Non-Clustered 인덱스를 생성할 수 있습니다.

 

출처

https://dev.mysql.com/doc/refman/8.0/en/memory-storage-engine.html#memory-storage-engine-indexes

https://hoing.io/archives/12610