부트캠프

[WIL] Middleware, N+1 문제 정리 및 해결

반응형

Middleware

서버에 클라이언트로부터 들어온 요청을 처리하는 중간에 기능상의 목적에 맞게 넣어 거쳐가는 함수들을 미들웨어라고 합니다.

여러 기능이 필요한 경우 여러 미들웨어를 넣을 수도 있습니다. 각각의 미들웨어는 next()라는 함수가 실행됨으로서 다음 미들웨어가 호출되어 실행됩니다.

 

또한 값을 담아서 다음 미들웨어로 해당 값을 전달해 줄 수도 있습니다.

 

1. 어플리케이션 레벨 미들웨어

어플리케이션 레벨 미들웨어란 express() 로 생성할 수 있는 app 객체의 app.use()나 app.METHOD() 함수를 이용해 미들웨어를 app 인스턴스에 바인딩하는 미들웨어 입니다. 마운트 경로가 없는 미들웨어 함수는 앱이 요청을 수신할 때마다 실행하게 됩니다.

 

ex) 

app.use((req, res, next) => {
  console.log('hello NodeJS');
}

 

 

 

 

2. 라우터 레벨 미들웨어

라우터 레벨은 express.Router()로 생성되는 router 인스턴스에 미들웨어가 들어가는 경우 입니다.

 

다음과 같이 /pages 로 시작하는 경로로 들어오는 경우 pageRouter 가 실행이 됩니다.

//app.js
const express = require('express');
const app = express();
const pageRouter = ('./routes/pages');
app.use('/pages', pageRouter);

 

TypeORM의 N + 1 문제

typeORM에서의 N + 1문제를 살펴보기 전에 두가지 로딩방식에 대해 짚고 넘어가야합니다.

 

lazy loading

lazy loading은 엔티티의 기본 설정입니다. 필요한 데이터만 가져온 후, 자식데이터들은 필요한 경우 가져옴으로서 DB를 한 번 더 탐색하는 것입니다. 따라서 효율적인 로딩방식입니다.

 

eager loading

eager loading은 필요한 엔티티들을 한번에 불러옵니다. 조인된 데이터들이 한번의 쿼리호출로 불러올 수 있습니다.

 

 

N + 1 문제

DB의 연결관계에서 발생하며 조회된 데이터 개수만큼 추가 쿼리가 실행되어 데이터를 가져옵니다. 이를 N + 1문제라고 합니다.

 

만약 Team이라는 테이블이 있고 팀에 소속되어있는 Player들이 있을 것입니다. 이 경우 Team을 조회할 때 player의 정보도 필요하다면 player들의 수만큼 N번 조회될 것입니다. 따라서 총 N + 1번의 조회 쿼리가 발생합니다.

 

 

해결방법

이 문제의 해결법은 default 로딩방식인 lazy loading에서 eager loading으로 바꾸는 것입니다. 

1. join을 통해서 해결할 수 있습니다.

2. relations 옵션을 적용하거나, QueryBuilder로 해결할 수 있습니다.

 

 

 

 

 

 

 

 

 

 

반응형