실험 환경
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 를 이용하는 방식이 더 좋아 보인다.
'프로그래밍 > Nest.js' 카테고리의 다른 글
[ Nest.js] 의존성 주입을 사용하는 이유와 장점 (0) | 2024.08.17 |
---|---|
[ Nest.js ] 대량의 데이터 삭제시 두가지 softDelete 방식 비교 (0) | 2024.07.23 |
[ Nest.js ] insert vs save : 둘 이상의 데이터 저장시 속도비교 (1) | 2024.07.22 |
[ Nest.js ] Middleware, Guard, Interceptor, Pipe, Filter (0) | 2024.07.20 |
[ Nest.js ] Lock 을 이용한 데이터 중복 저장 방지 구현 (0) | 2024.07.18 |