1. 문제 정의

데이터 베이스 성능을 개선하는 것은 품질 좋은 서버를 유지하기 위해서 필수적입니다.

하지만 개발자들이 수작업으로 데이터를 삽입한 후 테스트 하는 것은 한계가 있습니다.

따라서 업브렐라 개발팀은 Data Bulk Insert를 통해 DB에 대용량의 데이터를 삽입하고 성능 개선을 해보도록 하겠습니다.

2. Bulk Insert

2 - 1 데이터 만들기

우선 간단한 테이블인 협업지점 분류에 대한 데이터를 만들어보겠습니다.

classification 테이블은 id, type, name, latitude, longitude를 필드로 가지고 있는데, 이에 해당하는 데이터를 만들어 보겠습니다.

private static void makeStoreMeta() {
        String filePath = "store_meta.csv";
        Random random = new Random();

        try (FileWriter writer = new FileWriter(filePath)) {
            writer.append("id,classification_id,sub_classification_id,activated,deleted,name,category,latitude,longitude,password");
            writer.append("\n");

            for (int i = 1; i <= 1_000_000; i++) {
                writer.append(Integer.toString(i));
                writer.append(",");
                writer.append(Long.toString(random.nextLong() % 1000)); // classification_id
                writer.append(",");
                writer.append(Long.toString(random.nextLong() % 1000)); // sub_classification_id
                writer.append(",");
                writer.append(Integer.toString(random.nextInt(2))); // activated
                writer.append(",");
                writer.append(Integer.toString(random.nextInt(2))); // deleted
                writer.append(",");
                writer.append("Store_" + i); // name
                writer.append(",");
                writer.append("Category_" + (random.nextInt(10) + 1)); // category
                writer.append(",");
                writer.append(random.nextDouble() * 180 - 90 + ""); // latitude
                writer.append(",");
                writer.append(random.nextDouble() * 360 - 180 + ""); // longitude
                writer.append(",");
                writer.append("Password_" + i); // password
                writer.append("\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("CSV file created successfully at: " + filePath);
    }

위와 같이 FileWriter를 통해 백만건의 랜덤한 Classification을 생성하였습니다.

2 - 2 데이터 전송

이와 같은 대용량의 데이터를 서버에서 직접 만들 경우, CPU 부족 현상으로 서버가 다운될 우려가 있어 데이터 생성은 로컬에서 진행하였습니다.

이제 scp 명령어를 통해 데이터를 서버에 전송해주겠습니다.

scp -p classification.csv ubuntu@127.0.0.1:~/classification.csv

127.0.0.1에 서버의 ip를 기입하면 전송을 완료할 수 있습니다.

scp : 파일 전송 명령어  

p : 작성, 수정한 날짜를 보존함  

clsasification.csv 전송하려는 파일 명  

ubuntu@127.0.0.1 : 서버의 사용자명과 서버의 ip  

:~/classification.csv : 파일이 저장될 위치  

2 - 3 MySQL에 데이터 삽입

MySQL에서 파일을 Load해서 파일에 맞게 데이터를 INSERT 하기 위해서는 특정 위치에 해당 파일이 위치해야 합니다.

파일을 MySQL이 읽을 수 있는 위치로 이동시켜 줍니다.

sudo mv classification.csv /var/lib/mysql-files/

이제 파일을 이동시켰으니 데이터를 삽입해보도록 하겠습니다.

LOAD DATA INFILE '/var/lib/mysql-files/classification.csv' INTO TABLE classification
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
IGNORE 1 ROWS;

csv 파일을 생성할 때, 맨 윗 줄에 필드에 대한 설명을 적었기 때문에 ignore 1 rows를 해줍니다.

field 의 구분은 , 로 진행하고

line의 구분은 \n 으로 진행해줍니다.

3 마치며

이번 게시글을 통해 대용량의 데이터를 삽입하는 방법을 알아보았습니다.

다음 게시글에서는 대용량의 데이터를 통해 성능이 좋지 않은 API를 판별해보고 개선하는 방법에 대해 알아보겠습니다.