프레임워크/NestJS

NestJS TypeORM bulk insert로 데이터 입력하기

트리맨스 2024. 6. 17. 23:25
반응형

 

최근에 대량의 데이터 (4개의 칼럼, 200만개 가까이 되는 row)를 입력해야 할 일이 생겨서 NestJS 로직에서 데이터를 생성하는 중, Entity 생성 후 repository를 통해 데이터를 입력하는 방법은 상당히 속도가 느리다는 것을 알고 데이터 insert 속도를 찾기 위해 방법을 강구하던 중, bulk insert를 통해 속도를 올릴 수 있다는 것을 알게 되었다. 테스트를 위해서 간단히 환경을 만들어 보았다.

 

AppService

@Injectable()
export class AppService {
  constructor(
    @InjectRepository(UserEntity)
    private usersRepository: Repository<UserEntity>,
  ) {}

  async createUsers() {
    // faker.js를 사용한 가짜 유저 1만명 생성

    const data = this.getMockUserDatas();

    console.time('createUsers');
    for (const item of data) {
      const user = new UserEntity();
      user.name = item.name;
      user.email = item.email;
      await this.usersRepository.save(user);
    }
    console.timeEnd('createUsers');
  }

  async createUsersBulk() {
    const data = this.getMockUserDatas();

    console.time('createUsers');
    const users = data.map((item) => ({
      name: item.name,
      email: item.email,
    }));

    await this.usersRepository
      .createQueryBuilder()
      .insert()
      .into(UserEntity)
      .values(users)
      .execute();
    console.timeEnd('createUsers');
  }

  private getMockUserDatas() {
    return Array.from({ length: 10000 }, () => {
      return {
        name: faker.internet.userName(),
        email: faker.internet.email(),
      };
    });
  }
}

UserEntity

@Entity()
export class UserEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @Column()
  email: string;
}

 

createUsers와 createUsersBulk를 통해서 시간을 비교해 보았다.

Entity Bulk
5.202s 104.152ms
5.011s 79.357ms
4.522s 73.578ms
6.430s 87.201ms
4.806s 69.907ms

 

확실히 Bulk가 빠른 것을 볼 수 있다. 대량 데이터가 RDB에 입력되어야 할 때, 속도 최적화가 필요하다면 Bulk를 사용하는 것이 좋아 보인다.

 

반응형