본문 바로가기

IT/NOSQL

[DynamoDB] Secondary Index 설계원칙 및 고려사항

1. Secondary Index를 사용하는 이유

 

다음과 같은 은행 계좌를 관리하는 테이블을 생각해보자.

 

OriginCountry가 Germany인 모든 데이터를 불러온다고 가정하자. Query를 통해서 불러오기 위해선 AccountID와 CreationDate을 알고 있는 상황이어야 하지만

실제 Query상황에서는 이를 알 수 있는 방법이 없기 때문에 scan을 사용해야한다. scan을 사용하면 모든 데이터에 대해 검색을 실행하기 때문에 그만큼 실행속도가 느리다.

 

 

 

 

그러나 GSI를 사용하게 되면 다음과 같이 Primary Key를 원하는대로 바꿔서 테이블을 새로 생성 할 수 있다.

 

GSI Table(우측 테이블)을 생성하면서 기존 OriginCountry 속성을 Partition Key로 설정하였다.

기존 테이블에서 scan으로 처리하였던 요청을 query의 "KeyCondition" 함수를 이용하여 "OriginCountry eq Germany" 조건을 이용하게 되면 모두다 읽어버리는 scan보다 Read Capacity가 적게 들게된다.

 

출처 : https://www.youtube.com/watch?v=ihMOlb8EZKE

 

 

 

2. Secondary Index의 제약사항

 

다음 링크를 참조 바랍니다.

https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/Limits.html#limits-api [DynamoDB의 제한 값]

 

 

 

 

3. Secondary Index 설계 원칙

3.1. 인덱스의 수를 최소한으로 유지한다.

  • GSI의 경우, 별도의 용량단위를 부여받기 때문에, 원본 테이블의 sync를 맞추기 위해서는 추가로 용량을 소모하며 이를 줄이는 것이 비용, Storage, I/O 관점에서 효율적이다.
  • 그러므로, 자주 query가 이루어지지 않는 속성에 대해서는 Secondary Index를 생성하지 않는다

 

3.2. LSI 이용시 index에 없는 속성을 projection하지 않는다.

  • LSI의 경우, LSI테이블에 존재하지 않고 원본 테이블에 존재하는 속성에 대해서 쿼리가 가능하다.
  • 다음 다이어그램은 위 경우를 모식화한 것이다.

 

  • LSI에 존재하지 않는 속성에 대해 query를 하게 되면 원본 테이블에서 해당 속성에 대해 찾게 된다.
  • 그 결과, 그만큼 지연시간이 걸리며, row전체를 조회한 다음 projection을 실행하기 때문에 불필요한 데이터에 RCU를 소모하게 된다.
  • 결론적으로, LSI 역시 GSI처럼 필요없는 속성은 인덱스에 포함해서는 안된다.

 

3.3. Sparse Index의 활용

  • Dense Index와 Sparse Index에 대해서는 3.3.1과 3.3.2를 참고한다.
  • 밑의 인덱스 개념을 한마디로 쉽게 설명하면 다음문장과 같다.
  • "테이블에서 Partition Key다음으로 유일하고 특징을 나타내는 속성을 GSI의 Partition Key로 설정하여 Partition을 상황에 맞게 효율적으로 커스트마이징 한다."

 

3.3.1. Dense index

  • 하나의 레코드에 하나의 포인터가 할당된다.
  • 데이터의 모든 키(Partition Key, Sort Key, 일반키 등...)가 인덱스에서 표현이 가능한 형태이다.
  • 이러한 형태는 Primary Key를 이용하여 1회의 Disk I/O 만으로 원하는 레코드를 찾을 수 있는 장점이 있다.

 

 

 

 

 

 

3.3.2. Sparse index

  • Dense Index처럼 모든 키를 가지고 있기 되면 용량이 커진다.
  • 용량이 커지는 단점을 보완하기 위해 데이터 블록마다 하나의 key-pointer쌍을 가지게 하였다.
  • 이 같은 설계를 통해 여러개의 데이터를 하나의 블록으로 합침으로써 Dense Index보다 레코드의 개수를 줄일 수 있다.
  • 레코드의 개수가 줄어든 만큼 Disk I/O는 줄어들지만, 블록안의 속성에 대해 검색할 경우에는 추가적인 disk I/O를 요구할 수 있다.

 

 

 

 

 

 

 

4. 참고문헌