자바 에서 JDBC 는 MySQL 에 백만 급 데 이 터 를 삽입 하 는 인 스 턴 스 코드 를 실현 합 니 다.
DROP PROCEDURE IF EXISTS proc_initData;--
DELIMITER $
CREATE PROCEDURE proc_initData()
BEGIN
DECLARE i INT DEFAULT 1;
WHILE i<=100000 DO
INSERT INTO text VALUES(i,CONCAT(' ',i),'XXXXXXXXX');
SET i = i+1;
END WHILE;
END $
CALL proc_initData();
CALL proc 실행initData()후,원래 생각 했 는데 10W 조 의 데 이 터 를 30 분 정도 더 늦 추 면 해결 할 수 있 을 것 같 습 니 다.결국 저 는 LOL 2 개 를 친 후에 뒤 돌아 보 니 아직도 실행 되 고 있 습 니 다.이때 마음 이 완전히 멍 해 졌 습 니 다.제 가 세 번 째 데 이 터 를 다 친 후에 드디어 실 행 했 습 니 다.이런 방법 이 저 에 게 수백 만 개의 데 이 터 를 기다 리 게 한다 면 아침 에 출근 하고 오후 에 퇴근 해서 돌아 와 도 끝나 지 않 았 습 니까?10W 개의 데이터,그림 이 있 고 진실 이 있 습 니 다.JDBC 데이터베이스 에 일반 삽입 방식
뒤 를 살 펴 보 니 JDBC 일괄 작업 으로 데이터베이스 에 100 W+의 데 이 터 를 삽입 하 는 것 도 빠 른 것 같 습 니 다.
먼저 JDBC 가 데이터베이스 에 보통 삽입 하 는 방식 을 말씀 드 리 겠 습 니 다.간단 한 코드 는 대체적으로 다음 과 같 습 니 다.1000 개 를 순환 하고 중간 에 무 작위 수 치 를 추 가 했 습 니 다.자신 이 데 이 터 를 가지 고 테스트 해 야 하기 때문에 데 이 터 는 모두 똑 같 고 구분 하기 어렵 습 니 다.
private String url = "jdbc:mysql://localhost:3306/test01";
private String user = "root";
private String password = "123456";
@Test
public void Test(){
Connection conn = null;
PreparedStatement pstm =null;
ResultSet rt = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(url, user, password);
String sql = "INSERT INTO userinfo(uid,uname,uphone,uaddress) VALUES(?,CONCAT(' ',?),?,?)";
pstm = conn.prepareStatement(sql);
Long startTime = System.currentTimeMillis();
Random rand = new Random();
int a,b,c,d;
for (int i = 1; i <= 1000; i++) {
pstm.setInt(1, i);
pstm.setInt(2, i);
a = rand.nextInt(10);
b = rand.nextInt(10);
c = rand.nextInt(10);
d = rand.nextInt(10);
pstm.setString(3, "188"+a+"88"+b+c+"66"+d);
pstm.setString(4, "xxxxxxxxxx_"+"188"+a+"88"+b+c+"66"+d);27 pstm.executeUpdate();
}
Long endTime = System.currentTimeMillis();
System.out.println("OK, :" + (endTime - startTime));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}finally{
if(pstm!=null){
try {
pstm.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
}
출력 결과:OK,사용 시간:738199,단위 밀리초,즉 이런 방식 은 직접 데이터베이스 에서 순환 하 는 것 과 차이 가 많 지 않다.대량 처 리 를 논의 하기 전에 만 나 는 구 덩이 를 먼저 말 해 보 세 요.먼저 JDBC 가 연 결 된 url 에 rewriteBatched Statements 인 자 를 true 로 설정 하 는 것 이 대량 작업 의 전제 입 니 다.그 다음 에 my sql 드라이버 를 검사 할 때 5.1.13 이상 버 전(이 버 전보 다 지원 되 지 않 음)입 니 다.인터넷 에서 5.1.7 버 전 을 임의로 다운로드 한 다음 에 대량 작업(100 W 항목 삽입)을 수행 합 니 다.그 결과 드라이브 버 전이 너무 낮 아서 지원 되 지 않 아 자바 프로그램 을 중단 한 후에 도 my sql 은 데이터베이스 에 데 이 터 를 계속 삽입 하고 있 습 니 다.마지막 으로 데이터베이스 서 비 스 를 중단 해 야 합 니 다.
그렇다면 낮은 버 전의 드라이버 패 키 지 는 100 W+데 이 터 를 삽입 하면 무력 합 니까?실제로 또 다른 방식 이 있 는데,효율 에 비해 서 는 그래도 받 아들 일 수 있다.
트 랜 잭 션 제출 방식 사용
먼저 명령 의 제출 방식 을 false 로 설정 합 니 다.즉,conn.setAutoCommit(false)을 수 동 으로 제출 합 니 다.마지막 으로 모든 명령 이 실 행 된 후에 사무 conn.comit()를 제출 합 니 다.
private String url = "jdbc:mysql://localhost:3306/test01";
private String user = "root";
private String password = "123456";
@Test
public void Test(){
Connection conn = null;
PreparedStatement pstm =null;
ResultSet rt = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(url, user, password);
String sql = "INSERT INTO userinfo(uid,uname,uphone,uaddress) VALUES(?,CONCAT(' ',?),?,?)";
pstm = conn.prepareStatement(sql);
conn.setAutoCommit(false);
Long startTime = System.currentTimeMillis();
Random rand = new Random();
int a,b,c,d;
for (int i = 1; i <= 100000; i++) {
pstm.setInt(1, i);
pstm.setInt(2, i);
a = rand.nextInt(10);
b = rand.nextInt(10);
c = rand.nextInt(10);
d = rand.nextInt(10);
pstm.setString(3, "188"+a+"88"+b+c+"66"+d);
pstm.setString(4, "xxxxxxxxxx_"+"188"+a+"88"+b+c+"66"+d);
pstm.executeUpdate();
}
conn.commit();
Long endTime = System.currentTimeMillis();
System.out.println("OK, :" + (endTime - startTime));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}finally{
if(pstm!=null){
try {
pstm.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
}
상기 코드 는 10W 개의 데 이 터 를 삽입 하고 출력 결과:OK,사용 시간:18086,즉 18 초 정도 의 시간 입 니 다.이론 적 으로 100 W 즉 3 분 입 니 다.이렇게 하면 겨우 받 아들 일 수 있 습 니 다.일괄 처리
다음은 일괄 처리 입 니 다.5.1.13 이상 버 전의 드라이버 백 이 필요 합 니 다.
private String url = "jdbc:mysql://localhost:3306/test01?rewriteBatchedStatements=true";
private String user = "root";
private String password = "123456";
@Test
public void Test(){
Connection conn = null;
PreparedStatement pstm =null;
ResultSet rt = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(url, user, password);
String sql = "INSERT INTO userinfo(uid,uname,uphone,uaddress) VALUES(?,CONCAT(' ',?),?,?)";
pstm = conn.prepareStatement(sql);
Long startTime = System.currentTimeMillis();
Random rand = new Random();
int a,b,c,d;
for (int i = 1; i <= 100000; i++) {
pstm.setInt(1, i);
pstm.setInt(2, i);
a = rand.nextInt(10);
b = rand.nextInt(10);
c = rand.nextInt(10);
d = rand.nextInt(10);
pstm.setString(3, "188"+a+"88"+b+c+"66"+d);
pstm.setString(4, "xxxxxxxxxx_"+"188"+a+"88"+b+c+"66"+d);
pstm.addBatch();
}
pstm.executeBatch();
Long endTime = System.currentTimeMillis();
System.out.println("OK, :" + (endTime - startTime));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}finally{
if(pstm!=null){
try {
pstm.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
}
10W 출력 결과:OK,사용 시간:3386,겨우 3 초.일괄 작업+트 랜 잭 션
그리고 대량 작업+트 랜 잭 션 제출 하면?신기 효과 가 있 지 않 을까요?
private String url = "jdbc:mysql://localhost:3306/test01?rewriteBatchedStatements=true";
private String user = "root";
private String password = "123456";
@Test
public void Test(){
Connection conn = null;
PreparedStatement pstm =null;
ResultSet rt = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(url, user, password);
String sql = "INSERT INTO userinfo(uid,uname,uphone,uaddress) VALUES(?,CONCAT(' ',?),?,?)";
pstm = conn.prepareStatement(sql);
conn.setAutoCommit(false);
Long startTime = System.currentTimeMillis();
Random rand = new Random();
int a,b,c,d;
for (int i = 1; i <= 100000; i++) {
pstm.setInt(1, i);
pstm.setInt(2, i);
a = rand.nextInt(10);
b = rand.nextInt(10);
c = rand.nextInt(10);
d = rand.nextInt(10);
pstm.setString(3, "188"+a+"88"+b+c+"66"+d);
pstm.setString(4, "xxxxxxxxxx_"+"188"+a+"88"+b+c+"66"+d);
pstm.addBatch();
}
pstm.executeBatch();
conn.commit();
Long endTime = System.currentTimeMillis();
System.out.println("OK, :" + (endTime - startTime));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}finally{
if(pstm!=null){
try {
pstm.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
}
다음은 100 W 데이터 출력 대비 입 니 다.(5.1.17 버 전 MySql 드라이버 에서 테스트 하고 두 가지 방식 으로 데이터 테스트 결 과 를 교체 합 니 다)일괄 작업(10W)
일괄 작업+트 랜 잭 션 제출(10W)
일괄 작업(100 W)
일괄 오류+트 랜 잭 션 제출(100 W)
OK,사용 시간:3901
OK,사용 시간:3343
OK,사용 시간:44242
OK,사용 시간:39798
OK,사용 시간:4142
OK,사용 시간:2949
OK,사용 시간:44248
OK,사용 시간:39959
OK,사용 시간:3664
OK,사용 시간:2689
OK,사용 시간:44389
OK,사용 시간:39367
이 를 통 해 어느 정도 효율 이 향상 되 었 음 을 알 수 있 지만 뚜렷 하지 않다.물론 데이터 차이 가 그리 크 지 않 기 때문에 우연 한 인수 가 존재 할 수도 있다.왜냐하면 항목 당 3 번 만 측정 하기 때문이다.
사전 컴 파일+일괄 작업
인터넷 에 서 는 사전 컴 파일+대량 작업 방식 을 사용 하면 효율 을 높 일 수 있다 는 말 도 있 지만 본인 이 직접 측정 하면 효율 이 높 지 않 고 오히려 떨 어 지 는 것 은 테스트 데이터 와 관련 이 있 을 수 있 습 니 다.
사전 컴 파일 된 쓰기 방법 은 JDBC 연결 url 에 useServerPrepStmts=true 를 기록 하면 됩 니 다.
예:
private String url = "jdbc:mysql://localhost:3306/test01?useServerPrepStmts=true&rewriteBatchedStatements=true"
자,여기까지..이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Java 애플리케이션을 모든 SQL 데이터베이스와 연결그래서 오늘 이 기사를 통해 JDBC를 통해 Java 애플리케이션을 SQL 데이터베이스에 연결하기 위해 작성할 수 있는 각 줄을 설명하는 심층 가이드를 제공하여 그들과 모든 커뮤니티를 도우려고 합니다. JDBC는 J...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.