실험 환경

Nest.js, TypeORM , MySQL, TypeScript,

 

코드

1. update method

  async updateUsersNames(users: User[]) {
    const startTime = Date.now();
    for (const user of users) {
      await this.userRepository.update(user.id, user);
    }
    const duration = Date.now() - startTime;
    this.logger.log(
      `(update method) Bulk update of ${users.length} users completed in ${duration}ms`,
    );
  }

 

2.  createQueryBuilder method

 async updateUsersNamescreateQueryBuilder(users: User[]) {
    const startTime = Date.now();
    for (const user of users) {
      await this.userRepository
        .createQueryBuilder()
        .update(User)
        .set({ name: user.name })
        .where('id = :id', { id: user.id })
        .execute();
    }
    const duration = Date.now() - startTime;
    this.logger.log(
      `(createQueryBuilder) Bulk update of ${users.length} users completed in ${duration}ms`,
    );
  }

 

3. query 작성방식

 async updateUserNamesQuery(users: User[]) {
    const startTime = Date.now();
    const values = users
      .map((user) => `(${user.id}, ${user.name}, ${user.email})`)
      .join(', ');
    const query = `
        INSERT INTO user (id, name, email)
        VALUES ${values} as new
        ON DUPLICATE KEY UPDATE
          id = new.id,
          name = new.name,
          email = new.email,
      `;
    await this.userRepository.query(query);
    const duration = Date.now() - startTime;
    this.logger.log(
      `(query) Bulk update of ${users.length} users completed in ${duration}ms`,
    );
  }

 

4. save method

 async updateUsersNamesSave(users: User[]) {
    const startTime = Date.now();
    const values = users.map((user) => {
      const newUser = new User({ name: user.name, email: user.email });
      newUser.id = user.id;
      return newUser;
    });
    await this.userRepository.save(values);
    const duration = Date.now() - startTime;
    this.logger.log(
      `(save) Bulk update of ${users.length} users completed in ${duration}ms`,
    );
  }

 

 

Postman 으로 한번에 100개의 업데이트 요청 전송 결과

1. update

 

2 . createQuearyBuilder

 

3. query 작성

 

4. save

 

업데이트 방식 평균 처리 속도 (ms)
query 작성방식 7 ms
save 메소드 42.7ms
createQueryBuilder 메소드 68 ms
update 메소드 80 ms

 

1등 : query 작성방식

하지만 이 방식은 MySQL 과 같은 방식의 문법을 제공하는 데이터베이스에서만 사용이 가능하다는 단점이 존재한다.

 

2등: save 메소드

save 메소드는 주어진 데이터에 id 가 있으면 기존의 데이터 베이스 해당 데이터가 있는지 확인하고 있으면 업데이트를 한다.

주어진 데이터에 있는 id 가 데이터 베이스에 없으면 새로운 엔티티로 간주하고 데이터를 저장한다.

  - 데이터베이스가 자동으로 ID를 생성하도록 설정된 경우 : 주어진 id 를 무시하고 데이터베이스가 새로운 id 를 생성한다.

   

3등 : createQueryBuilder

for 문을 이용했지만, 이 방식을 이용하면 조인, 복잡한 조건, 서브쿼리 등을 활용할 수 있어서 유용해 보인다.

 

4등 : update 메소드

createQueryBuilder 와 같은 복잡한 쿼리 구성을 제공하지않아 간단한 업데이트를 할때 활용하면 좋을 것 같다.

 

 

 

결론

범용성을 고려하여 TypeORM 에서 제공해주는 메소드 save 를 이용하는 것이 좋아 보인다.

복잡한 방식의 조건 처리라면 createQueryBuilder  를 이용하는 방식이 더 좋아 보인다.

 

 

 

+ Recent posts