.take(n)도 QueryBuilder에서 리턴되는 정보의 개수를 n개로 하는 것이고, .limit(n)도 .take(n)와 동일한 리턴 결과값을 나타내는데, 왜 .limit(n)은 예상과 다르게 쿼리가 작동하고, .take(n)는 예상대로 값을 리턴하는지 의문점이 들게 되었다.
찾아보니 .limit(n)의 경우, Query를 전송하기 이전에 QueryBuilder 내부에 포함된 것으로 SQL문으로 LIMIT n 으로 추가되지만, .take(n)의 경우, .take 이후의 .getMany( );를 통해 먼저 전체 결과값을 배열로 불러와 IN 문을 통해 다시 한번 더 n개만을 가져오는 방식으로 작동한다.
TypeORM QueryBuilder에서 .join과 .limit(n)을 동시에 사용할 시 실제 쿼리를 살펴보면, JOIN시킨 테이블(B)의 n개를 가진 JOIN 당한 테이블(A) 1개를 가져오는 방식으로 작동한다. 위와 같이 작동하는 이유는 이미 A라는 테이블에 LIMIT n을 통해 n개를 가져온 뒤, B 테이블과 JOIN을 하기 때문이다. 위와 같은 문제가 발생하지 않으려면, .take(n)을 사용하거나, 성능적인 면에서 직접 쿼리문을 작성하는 것이 좋을 것 같다.
[TypeORM] QueryBuilder의 limit 과 take의 차이
CreateQueryBuilder를 사용하여 API를 구성하다가 .leftJoin으로 현재 QueryBuilder가 위치한 Entity외에 다른 JOIN Table에서 정보를 가져와서 필터링을 해야하는 경우가 생겼다. 해당 API 실행 계획은 다음과 같았다.
위의 실행 계획을 createQueryBuilder에 해당 JOIN테이블을 leftJoin하는 방식으로 구현하였는데 .limit(n)을 추가하면, 쿼리가 고장나서 예상과 다른 쿼리를 2번을 날리고 스토리가 2개만 들어있는 Array가 2번 리턴되는 이슈가 발생하였다.
분명 .limit(n)이 SQL문의 LIMIT 인 것으로 알고 있었는데 TypeORM 공식 문서의 QueryBuilder-select using query builder에서 .limit(n)에 대한 설명을 찾아보니 아래와 같이 도움말이 있었다.
위의 도움말을 살펴보면 JOIN이나 SubQuery를 사용하는 경우, LIMIT이 예상대로 작동되지않을 것이니 take(n)를 대신 사용하라고 되어있다. TypeORM 깃헙 이슈에 가보니 관련 이슈가 여러 개 존재했다.
.take(n)의 경우, Pagination을 적용할 때 앞에서부터 n개의 정보를 가져올 때 사용하는 것이라고 알고 있었다. 실제로 위에서 문제가 되었던 코드를 다음과 같이 수정하니 예상과 일치되는 값을 리턴하였다.
.take(n)도 QueryBuilder에서 리턴되는 정보의 개수를 n개로 하는 것이고, .limit(n)도 .take(n)와 동일한 리턴 결과값을 나타내는데, 왜 .limit(n)은 예상과 다르게 쿼리가 작동하고, .take(n)는 예상대로 값을 리턴하는지 의문점이 들게 되었다.
찾아보니 .limit(n)의 경우, Query를 전송하기 이전에 QueryBuilder 내부에 포함된 것으로 SQL문으로 LIMIT n 으로 추가되지만, .take(n)의 경우, .take 이후의 .getMany( );를 통해 먼저 전체 결과값을 배열로 불러와 IN 문을 통해 다시 한번 더 n개만을 가져오는 방식으로 작동한다.
TypeORM QueryBuilder에서 .join과 .limit(n)을 동시에 사용할 시 실제 쿼리를 살펴보면, JOIN시킨 테이블(B)의 n개를 가진 JOIN 당한 테이블(A) 1개를 가져오는 방식으로 작동한다. 위와 같이 작동하는 이유는 이미 A라는 테이블에 LIMIT n을 통해 n개를 가져온 뒤, B 테이블과 JOIN을 하기 때문이다. 위와 같은 문제가 발생하지 않으려면, .take(n)을 사용하거나, 성능적인 면에서 직접 쿼리문을 작성하는 것이 좋을 것 같다.
참고 ) https://stackoverflow.com/questions/68468192/difference-between-limit-and-take-in-typeorm
'개발 > TypeORM' 카테고리의 다른 글