Rlog

TypeORM DistinctQuery 가 원치 않는데도 나는 문제 본문

TypeScript

TypeORM DistinctQuery 가 원치 않는데도 나는 문제

dev_roach 2022. 5. 27. 12:47
728x90

현재 팀내 Legacy Code 에서는 TS 기반의 TypeORM 이 존재하는데 걷어내야 될 존재라 Flow 만알고, 이 프레임워크가 어떻게 돌아가는지는 잘 공부하진 않았다. Migration 대상에 시간을 투자하는건 별로 효율적이지 못하다고 생각해서이다. 최근에 SlowQuery 를 개선하며 DBA 분과 이야기하는데, 왜 이부분에서 distinct query 가 예전부터 날라오는지 잘 모르겠다. 라며 이야기를 해주셨고, 그 코드를 한번 파헤쳐봤는데 distinct 가 될만한 거리는 보이지 않았다.

 

TypeORM 에서 distinct 를 하기 위해서는 .disctinct(true) 를 하거나 .select('select distinct a') 이런식으로 적어줘야 한다고 알고 있었다. 하지만 우리의 코드에는 이런 부분이 단 하나도 존재하지 않았는데, distinct 쿼리가 지속적으로 발생하고 있었다. 여기서 왜 distinct 를 지워야 하냐고 물어본다면, distinct 는 DB 가 가져온 결과값중 중복을 걸러내는 작업을 해야하므로, memory table 을 구성하게 된다. 사실 중복이 아닌데 distinct query 를 적는다는건 memory table 을 쓸모없이 구성하고 validation 해! 라고 하는것과 비슷한뜻이다.

 

그래서 구글에 검색을 하고, TypeORM 이슈를 보다가 알게 된것인데, 이런 구문이 하나 있었다.

Also, first "distinct" query warms up database cache, so i belive "real" query should be very fast after that 

지금 우리의 코드는 대략적으로 아래와 같은 코드이다.

 const data = await query
     .take(size)
     .skip((page - 1) * size)
     .orderBy({'created': sort || 'ASC'})
     .getManyAndCount();

여기서 take / size 를 이용해서 TypeORM 의 pagination 을 이용할경우 database cache warm up 을 하기 위한, distinct 쿼리를 발사하는 것이 였다. 나는 한가지 의문인점은, TypeORM 이 옵션으로 받는것도 아니라 자기 마음대로 database cache 성능을 생각해주는게 맞는가? (근데 이건 내가 틀리게 아는것일수 있다. 내가 찾아본한 그냥 자동으로 해주고 있던것이다.) 그리고 database cache 를 warm up 한다고 중복 쿼리를 발사하는게 맞는가..? 이게 뒤의 쿼리가 빠른게 의미가 있나? 쿼리를 두번 쏘는건데.. 그냥 내 상식선에서는 이해가지 않는 행동이였다. 그리고 보통 DB 는 많이 날라온 쿼리를 캐싱하는데, 굳이 ORM 에서 두번 쏘고 이럴 필요가 있을까? 그럼 차라리 JPA 의 Persistence Context 나 Session Cache 처럼 하는게 더 맞지 않나? 등의 생각이 들었다.

 

결론적으로 해결책은 TypeORM 의 paging 을 쓰는것이 아닌 단순 limit offset 으로만 바꿔주면 해결될 문제였다.

const data = await query
    .orderBy({'created': sort || 'ASC'})
    .limit(size)
    .offset((page - 1) * size)
    .getManyAndCount()

이런걸 보면 볼수록 날쿼리가 오히려 복잡도를 더 낮춘다는 생각도 많이 든다.

'TypeScript' 카테고리의 다른 글

[TypeScript] Json 파일 읽어와서 type 으로 변환하기  (0) 2021.12.19