Real My Sql 8.0 - 인덱스

차지현·2022년 11월 13일
0

인덱싱

인덱싱이란, 데이터를 효율적으로 식별할수 있게 컬럼들의 값을 key로, 레코드를 저장한 주소를 value로 삼아 인덱스를 만들어두는 것입니다.
인덱스 데이터가 많아지면 원하는 데이터를 식별해내는데 시간이 오래 걸리므로,
데이터를 저장시 컬럼의 값을 주어진 순서로 미리 정렬하려 보관합니다.

또한, 인덱스는 SortedList 자료구조를 차용하고 있습니다.
SortedList는 저장되는 값을 항상 정렬된 상태로 유지하는 자료구조이고,
ArrayList는 값을 저장되는 순서 그대로 유지하는 자료구조입니다.

따라서 저장시점에 SortedList는 자원을 비교적 많이 사용합니다.
하지만 정렬된 상태를 유지하고있으니, 원하는값을 빨리 찾아올 수 있습니다.
정리하자면 인덱싱은 저장성능과 읽기성능의 트레이드 오프입니다.
테이블에서 인덱스를 하나 더 추가할지를 결정하는것은 데이터의 저장속도를 얼마나 희생시켜서 읽기속도를 높일것인가에 따라 결정하는것입니다.


B-Tree || Hash

B-Tree알고리즘이란, RDBMS에서 가장 일반적으로 사용되는 인덱스 알고리즘입니다.
해당 알고리즘은 컬럼의 값을 변형하지않고 원래의 값을 이용해 인덱싱하는 알고리즘입니다.(다만 왼쪽값(Prefix)을 기준으로 식별함)

Hash 인덱스 알고리즘은, 컬럼의 값으로 해시값을 계산하여 인덱싱하는 알고리즘으로, 빠르지만, 값을 변형하여 인덱싱하므로, Prefix일치와 같이 값 일부만 검색하거나 범위를 검색할때는 Hash알고리즘을 사용할 수 없습니다. Hash인덱스는 주로 메모리 기반의 데이터베이스에서 많이 사용합니다.


인덱스 레인지 스캔 || 인덱스 풀 스캔

인덱스 레인지 스캔은, 작업범위 결정 조건에 따라 일부 데이터 범위를 스캔합니다.

  1. 인덱스에서 조건을 만족하는 값이 저장된 위치를 찾는다.(인덱스 탐색)
  2. 1번에서 탐색된 위치부터 필요한만큼 인덱스를 차례대로 쭉 읽는다. 이 과정을 인덱스 스캔이라고 한다.
  3. 2번에서 읽어들인 인덱스키와 레코드주소를 이용해 레코드가 저장된 페이지를 가져오고, 최종레코드를 읽어온다.

인덱스 풀스캔은 인덱스의 처음부터 끝까지 모두읽는 방식입니다. 쿼리의 조건절에 사용된컬럼이 인덱스의 첫번째 컬럼이 아닌경우 인덱스 풀스캔 방식이 사용됩니다. 쿼리의 조건절이 인덱스에 명시된 컬럼으로만 처리할 수 있는경우 주로 사용되며, 인덱스뿐만아니라 데이터 레코드까지 모두 읽어야할때 사용되는 테이블 풀스캔보다는 효율적입니다.

작성한 쿼리문이 인덱스레인지 스캔을 사용했는지, 인덱스 풀스캔을 사용했는지 확인하기 위해 쿼리문 앞에 EXPLAIN 예약어를 기입합니다.
결과 레코드의 type컬럼이 index 라면 인덱스 풀스캔이 사용된 것이고, range인 경우는 인덱스 레인지 스캔이 사용된 것입니다.

인덱스 스캔을 효율순으로 나열하면
인덱스 레인지 스캔 > 인덱스 풀 스캔 > 테이블 풀 스캔
입니다.


다중 컬럼 인덱스

다중컬럼인덱스는 두개 이상의 컬럼으로 이루어진 인덱스입니다.
인덱스 생성시, 인덱스내 컬럼의 순서를 고심하여 구성해야합니다.
일반적으로는 작업범위를 결정할수있는 조건의 컬럼을 선순위로, 필터링(체크)만 지원하는 조건의 컬럼을 후순위로 선정합니다.
인덱스의 컬럼구성이 (col1, col2, col3, col4)로 이루어져있는 경우,
col1을 최우선으로 정렬한 후 col2는 col1의 정렬순서를 기반하여 정렬됩니다.
따라서 col2만 단독으로 정렬하였을때 더 앞선 순서의 value가, col1정렬을 먼저 수행한후 col2정렬이 수행된 경우에는 후순위가 될수도 있습니다.

작업범위결정조건으로 인덱스를 사용하는경우
1. 값을 동등비교 (=, IN)
2. 대소비교(< , >)
3. LIKE 좌측일치패턴(LIKE '상수%')


클러스터링 인덱스

테이블의 프라이머리 키값이 비슷한 레코드끼리 묶어서 저장하는것을 클러스터링 인덱스라고 합니다. 레코드의 저장위치는 프라이머리키값에 의해 결정되며, 이는 키값이 변경된다면 그 레코드의 물리적인 저장위치가 바뀌어야함을 의미하기도 합니다.
여기서 프라이머리키는 클러스터링 키라고도 표현합니다.
일반적으로 InnoDB와 같이 항상 클러스터링 인덱스로 저장되는 테이블은 프라이머리 키 기반의 검색이 매우 빠르고, 대신 레코드의 저장이나 프라이머리키 변경이 상대적으로 느립니다.
InnoDB테이블이 프라이머리 키 없이 구성될경우에는, NOT NULL 옵션의 유니크 인덱스중에서 첫번째 인덱스를 클러스터링 키로 선택하고, 이 또한 존재하지 않으면 자동으로 유니크한 값을 가지도록 증가되는 컬럼을 내부적으로 추가후(사용자가 직접 접근 불가능), 클러스터링 키로 선택합니다.

세컨더리 인덱스에 미치는 영향

InnoDB테이블(클러스터링 테이블)의 모든 세컨더리 인덱스는 해당 레코드가 저장된 주소가 아니라, 프라이머리 키값을 저장하도록 구현되어있습니다. 만약 세컨더리 인덱스가 레코드 저장주소를 저장했더라면, 클러스터링 키 값이 변경될때마다 데이터 레코드의 주소가 변경되고, 그때마다 해당테이블의 모든 인덱스에 저장된 주솟값을 변경해야하는 오버헤드가 발생하기에, 세컨더리인덱스-PK-최종레코드 순으로 접근하게 됩니다.


profile
의 가상메모리 공간📂

0개의 댓글