저는 NestJS 프레임워크에서 tpyeorm을 사용해 데이터를 조회할 때 findBy 혹은 findOneBy 메서드를 사용해 왔습니다. 이때 메서드명을 통해 하나의 데이터만 조회하기 위해서는 findOneBy를 이용했고, 여러 데이터를 조회하기 위해서는 findBy를 사용했습니다. 하지만 만약 findBy를 이용해 하나의 데이터를 조회한다면 굳이 findOneBy 메서드의 필요성이 있을까? 혹시 하나의 데이터를 조회하는데 최적화된 방법이 findOneBy일까? 고민되었습니다. 이런 고민을 토대로 제가 알아본 findBy VS findOneBy, 어떤 메서드가 더 효율적인지에 대해 제 의견을 공유해보려합니다.
메서드 및 쿼리
findBy 메서드 쿼리
먼저 findBy 메서드를 사용했을 때는 하나의 쿼리만 실행됨을 확인할 수 있습니다. 아래가 findBy 메서드 코드 및 쿼리 예제입니다.
- id값이 16인 posts를 조회하기 위한 코드
const posts = await this.postRepository.findBy({ id: 16 });
- 쿼리
query:
SELECT
`Post`.`id` AS `Post_id`,
생략
`Post__user`.`id` AS `Post__user_id`,
생략
FROM
`post` `Post`
LEFT JOIN
`user` `Post__user`
ON
`Post__user`.`id`=`Post`.`userId`
WHERE
((`Post`.`id` = ?)) -- PARAMETERS: [16]
하지만 이 경우에는 반환된 데이터가 배열로 확인됩니다. 즉, 하나의 데이터만 조회하기 위함이 목적이라면 다음과 같이 배열 속 데이터를 이용해야 합니다.
const posts = await this.postRepository.findBy({ id: 16 });
const post = posts[0];
findOneBy 메서드 쿼리
먼저 findOneBy 메서드를 사용했을 때는 두 개 쿼리를 실행됨을 확인할 수 있습니다. 아래가 findOneBy 메서드 코드 및 쿼리 예제입니다.
- id값이 16인 post를 조회하기 위한 코드
const post = await this.postRepository.findOneBy({ id: 16 });
- 쿼리
query:
SELECT DISTINCT
`distinctAlias`.`Post_id` AS `ids_Post_id`
FROM (
SELECT
`Post`.`id` AS `Post_id`,
생략
`Post__user`.`id` AS `Post__user_id`,
생략
FROM
`post` `Post`
LEFT JOIN
`user` `Post__user`
ON
`Post__user`.`id`=`Post`.`userId`
WHERE
((`Post`.`id` = ?))
)
`distinctAlias`
ORDER BY
`Post_id` ASC LIMIT 1 -- PARAMETERS: [16]
query:
SELECT
`Post`.`id` AS `Post_id`,
생략
`Post__user`.`id` AS `Post__user_id`,
생략
FROM
`post` `Post`
LEFT JOIN
`user` `Post__user`
ON
`Post__user`.`id`=`Post`.`userId`
WHERE
( ((`Post`.`id` = ?)) )
AND
( `Post`.`id` IN (16) ) -- PARAMETERS: [16]
이 경우에는 첫 번째 쿼리에서 데이터를 먼저 서브쿼리로 가져오고 여기서 DISTINCT 적용 후 pk값(id)를 추출합니다. 그리고 두번째 쿼리에서는 findBy 메서드와 거의 동일한 쿼리로 데이터를 조회 후 여기서 pk값(id)이 첫번째 쿼리에서 확인한 값과 같은 데이터만 조회합니다.
그래서 어떤 메서드가 더 효율적인가?
저는 개인적으로 findBy가 더 효율적이라고 생각합니다.
간단하게 쿼리 2번 실행 vs 쿼리 1번 실행만 비교해도 1번만 쿼리를 실행하는 것이 더 효율적일 수밖에 없고, 보통은 pk값(id)을 이용해 데이터를 조회하는 경우가 많기 때문에 이 경우에는 애초에 고유한 데이터 조회가 보장되기 때문입니다.
✅ 즉, 특정 데이터 한 개만 조회하고 싶다면 pk값을 이용해 findBy 메서드를 활용하고, 반환된 값의 0번째 인덱스 데이터를 추출하는 것이 더 좋다고 생각합니다.
'데이터베이스, ORM > TypeORM' 카테고리의 다른 글
[TypeORM] 내가 트랜잭션을 사용하는 이유와 조심해야할 부분 (0) | 2024.12.17 |
---|---|
[TypeORM] SQL 쿼리 튜닝 - 2. 외래키 정보 join없이 조회하기 (0) | 2024.12.02 |
[TypeORM] @OneToMany, @ManyToOne - 옵션: onDelete / onUpdate (0) | 2024.11.23 |
[TypeORM] @OneToMany, @ManyToOne - 옵션: eager / lazy (0) | 2024.11.23 |
[TypeORM] @OneToMany, @ManyToOne - 옵션: cascade (0) | 2024.11.23 |