[NoSQL] AWS DynamoDB 사용기 - GSI 올바르게 사용하기

정 승 연·2025년 1월 29일
0


createdAt 을 GSI로 설정하여 날짜별 조회를 하려했다. 데이터 생성 초기에는 빠른 시간 내에 데이터 조회가 가능했으나, 데이터가 쌓이면서 GSI를 통한 조회 시간은 7초 이상을 넘어가기 시작했다.

 val allUserRoutine = userTaskRepository.findAllByGSIAndCreatedAt(
            KeyBuilder.userTaskPK(storeId),
            KeyBuilder.userTaskSK(null, null),
            todayStart,
            todayEnd
        )
override fun findAllByGSIAndCreatedAt(pk: String, sk: String, startTime: String, endTime:String): List<T> {

            val conditional: QueryConditional = QueryConditional.sortBeginsWith(
                Key.builder()
                    .partitionValue(pk)
                    .sortValue(sk)
                    .build()
            )

            val queryRequest = QueryEnhancedRequest.builder()
                .queryConditional(conditional)
                .filterExpression(
                    Expression.builder()
                        .expression("created_at BETWEEN :start AND :end")
                        .expressionValues(
                            mapOf(
                                ":start" to AttributeValue.builder().s(startTime).build(),
                                ":end" to AttributeValue.builder().s(endTime).build()
                            )
                        )
                        .build()
                )
                .build()

            return dynamoDbTable.query(queryRequest).items().toList()

        }

GSI와 createdAt 을 이용해 조회하는 구현체에 문제가 있어 느려진건가하는 생각이 들었다. 하지만 조회 과정에서는 문제가 없었고, 적합한 인덱스 방식을 사용했는지에 대한 문제였다.

dynamodb의 데이터 조회 방식에는 query 방식과 scan 방식이 있는데 scan보다 query 가 훨씬 효율적이며 PK를 기반으로 데이터를 조회하므로 적합한 인덱스를 설정했다면 빠르게 작동한다.

따라서 적합한 pk 를 설정했는지 고민하는게 첫번쨰 순서였다.

기존 DB 설계시에는 날짜별 조회라는 조건이 없어 데이터의 고유 id값을 조합해 pk,sk 를 구성했다. 하지만 이후에 날짜별로 조회하는 기능의 필요성을 깨닫고 GSI로 createdAt을 설정해 between을 이용해 날짜별 조회를 구현했다.

초기 DB설계에 있어서 확장성을 고려하지 못하고 pk,sk를 설정했던 실수였다.

이번 버전 업데이트부터는 날짜별 조회가 필수적이고 그 조회시간이 빨라야하기에 pk,sk 패턴을 바꿔야겠다 생각이 들었다.

기존에는

pk : STORE#{storeId}

sk : ROUTINE#{routineId}#USERTASK#{userTaskId}

  • routine : 업무
  • userTask : 업무에 종속되는 하위 세부 사항

이렇게 pk,sk 를 설정해 routineId별 세부 사항을 조회하는 등의 조회 조건을 가졌다. 하지만 이에 createdAt 을 추가했다.

pk : STORE#{storeId}

sk : CREATEDAT#{createdAt}#ROUTINE#{routineId}#USERTASK#{userTaskId}

  • routine : 업무
  • userTask : 업무에 종속되는 하위 세부 사항

0개의 댓글