Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

컬렉션 목록 가져오기 N+1 문제 #1

Open
khcho0125 opened this issue Apr 29, 2023 · 0 comments
Open

컬렉션 목록 가져오기 N+1 문제 #1

khcho0125 opened this issue Apr 29, 2023 · 0 comments
Assignees
Labels
record 과제를 진행하며 마주친 문제입니다.

Comments

@khcho0125
Copy link
Owner

khcho0125 commented Apr 29, 2023

계층적인 컬렉션을 구상하였을 때 '아... N+1 문제 어떻게 해결하지' 라는 생각이 먼저 들었습니다.
물론, Spring Boot JPAFetch Join이나 EntityGraph 등 여러 방법이 있고 적용한 경험이 있지만
Ktor Framework에서 해결할 수 있는지 알 수 없었기 때문에 걱정이 있었습니다.

✏️ 일단 부딪쳐보자~

여러 API를 완성하고 컬렉션 목록 가져오기 API를 만들어야 할 때가 왔습니다.

첫 번째로, 조인을 사용하는 방법을 구상했습니다.

  • 조인된 Row를 가져올 수 있지만, 데이터 가공이 어려웠기 때문에 다른 방법을 찾아야 했습니다.

두 번째로, Kotlin Exposed DAO를 사용했습니다.

  • DAO는 유용한 메서드와 자동 매핑을 지원하기 때문에 가능하지 않을까 생각했습니다.
    DAO의 즉시 로딩을 사용해 같은 계층의 컬렉션을 한 번에 가져오는 쿼리를 사용할 수 있었습니다.
  • 하지만 DAO의 메서드를 사용하면 쿼리가 중복으로 요청되는 문제가 추가로 발생하였습니다.
    image

    중복된 IS NULL LIMIT 20 쿼리

세 번째로, Kotlin Exposed DSL을 사용했습니다.

  • DAO에서 IN 쿼리가 보내지는 걸 확인하고 DSL로 시도하게 되었습니다.
  • 컬렉션 뿐만 아니라 연관된 하이라이트까지 IN 쿼리로 요청하면서 N+1 문제를 해결할 수 있었습니다.
    image

    한 번만 수행되는 IS NULL LIMIT 20 쿼리

마지막으로, IN 쿼리의 성능을 확인했습니다.

  • EXPLAIN문 쿼리로 DB가 어떤 SCAN을 확인할 수 있습니다.
    image
    필터링된 100개의 row에 대해 최대 37개의 아이디로 조회했을 때, Index Range Scan을 통해 접근하였습니다.
EXPLAIN SELECT tbl_collection.id, tbl_collection.user_id, tbl_collection.`name`, tbl_collection.parent_id FROM tbl_collection WHERE tbl_collection.parent_id IN (1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 15, 16, 17, 18, 19, 21, 24, 28, 30, 50, 56, 58, 59, 60, 61, 62, 64, 68, 70, 71, 89, 90, 91, 97, 99, 100);

최적화하는 과정에서 데이터베이스와 Ktor에 대해 공부한 점이 많아 재미있었습니다.

@khcho0125 khcho0125 added the record 과제를 진행하며 마주친 문제입니다. label Apr 29, 2023
@khcho0125 khcho0125 self-assigned this Apr 29, 2023
@khcho0125 khcho0125 pinned this issue Apr 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
record 과제를 진행하며 마주친 문제입니다.
Projects
None yet
Development

No branches or pull requests

1 participant