프로젝트 마다 성격이 다르고 요청하는 부분이 다르지만.. 대부분은 거의 비슷한 요청을 합니다. 이번에 발생한 데이터베이스 입력 부분은 다른 프로젝트에서도 발생될 수 있는 부분이라 정리를 해봤습니다. 현재 프로젝트에서 모든 데이터베이스 입력은 건 by 건으로 동작하고 있습니다.
만약 사용자가 1000명의 데이터 입력을 요청하면..
for(int i=0; i<1000; i++) {
// 데이터베이스 입력
}
이와 같은 형식으로 하다 보니 데이터베이스에 입력하는데 소요되는 시간이 아주 많이 걸립니다.
그래서 구글링을 해본 결과 MYSQL 데이터베이스에서 입력하는 방법 3가지로 요약됩니다.
- INSERT INTO TEST_TABLE VALUES ( , , , ); * 1000
- INSERT INTO TEST_TABLE VALUES (,,,),(,,,)… (,,,);
- LOAD DATA IN FILE…
빠른 순서대로 하면 3 > 2 > 1 순입니다.
LOAD DATA 파일은 빠르지만 매번 파일을 생성해야 하는 번거러움이 있습니다. 그래서 두번째로 빠른 방법을 선택해서 테스트를 해봤습니다.
INSERT_TEST (
ID varchar(20),
NAME varchar(50)
)
위의 테이블에 각각 2000건씩 입력을 하는 테스트입니다.
Class.forName("com.mysql.jdbc.Driver");
Connection conn
= DriverManager
.getConnection(
"jdbc:mysql://localhost:3306/test?characterEncoding=utf8"
, "coozplz"
, "coozplz"
);
Statement stmt1 = conn.createStatement();
long sTime = System.currentTimeMillis();
for(int i=0; i< 2000; i++) {
String sql = "INSERT INTO insert_test values ('"
+i+"', 'test입니다.')";
stmt1.execute(sql);
}
System.out.println("exec 2000 times "
+(System.currentTimeMillis() - sTime) / 1000.0);
Statement stmt2 = conn.createStatement();
long sTime2 = System.currentTimeMillis();
StringBuilder sb = new StringBuilder("INSERT INTO insert_test values ");
for(int i=0; i< 2000; i++) {
sb.append("('"+i+"','test입니다.')");
if(i < 2000-1) {
sb.append(",");
}
}
stmt2.execute(sb.toString());
System.out.println("exec 1 time "
+(System.currentTimeMillis() - sTime2) / 1000.0);
최대한 간단하게 만들었습니다.
위에 보면 stmt1.execute(sql) * 2000 아래는 stmt2.execute(sb.tostring()) 이 한번 도는 것을 확인 할 수 있습니다.
해당 결과는
exec 2000 times 64.41 exec 1 time 0.151 |
2천건에서 간단한 테스트 프로그램으로도 이정도의 차이가 나지만 실제 운영 중인 서버에서는 더 많은 차이가 날 수 있습니다…