먼저, 3 개의 JDBC 배치 삽입 프로그래밍 방법이 도입되어이를 비교합니다. 특정 내용은 다음과 같습니다
JDBC 배치 삽입은 주로 데이터 가져 오기 및 로깅에 사용됩니다. 로그는 일반적으로 파일에 일반적으로 작성되기 때문입니다.
MySQL 5.1.5의 JDBC 드라이버를 사용하여 3 가지보다 일반적으로 사용되는 세 가지 방법을 테스트했습니다.
방법 1 : 준비 상태를 사용하여 배치를 추가하십시오
try {class.forname ( "com.mysql.jdbc.driver"); conn = drivermanager.getConnection (O_URL, 사용자 이름, 암호); conn.setAutocommit (false); 문자열 sql = "adlogs 삽입 (ip, 웹 사이트, yyyymmdd, hour, object_id) 값 (?,?,?,?)"; preparedstatement perst = conn.preparestatement (sql, resultset.type_scroll_sensitive, resultset.concur_read_only); for (int x = 0; x <size; x ++) {prest.setString (1, "192.168.1.1"); Prest.setString (2, "LocalHost"); Prest.SetString (3, "20081009"); Prest.SetInt (4, 8); Prest.SetString (5, "11111111"); prest.addbatch (); } prest.executebatch (); conn.commit (); conn.close (); } catch (sqlexception ex) {logger.getLogger (myLogger.class.getName ()). log (level.severe, null, ex); } catch (classNotFoundException ex) {logger.getLogger (myLogger.class.getName ()). log (level.severe, null, ex); } 문을 작성할 때 다음 두 매개 변수의 의미를 설명하십시오.
첫 번째 매개 변수는 resultset 유형을 지정합니다. 옵션은 다음과 같습니다.
type_forward_only : 기본 유형. 포워드 액세스는 한 번만 허용되며 다른 사용자가 데이터베이스에 대한 변경에 의해 영향을받지 않습니다.
type_scroll_insensentive : 목록에서 앞으로 또는 뒤로 이동하고 목록의 네 번째 레코드로 이동하거나 현재 위치에서 두 레코드를 뒤로 이동하는 것과 같은 특정 위치조차도 가능합니다. 다른 사용자가 데이터베이스에 대한 변경에 영향을받지 않습니다.
type_scroll_sensitive : type_scroll_insensitive와 마찬가지로 레코드에 위치가 허용됩니다. 이 유형은 다른 사용자의 변경에 영향을받습니다. 사용자가 쿼리를 실행 한 후 레코드를 삭제하면 결과 세트에서 해당 레코드가 사라집니다. 마찬가지로, 데이터 값에 대한 변경은 결과 세트에 반영됩니다.
두 번째 매개 변수는 resultset의 동시성을 설정하여 resultSet을 업데이트 할 수 있는지 여부를 결정합니다. 옵션은 다음과 같습니다.
concur_Read_only : 이것은 기본값이며 업데이트 할 수 없다고 지정합니다.
resultset concur_updatable : resultSet을 업데이트 할 수 있다고 지정합니다
방법 2 : 배치 방법을 추가하기 위해 명령문을 사용하십시오
conn.setAutocommit (false); Statement stmt = conn.createstatement (resultset.type_scroll_sensitive, resultet.concur_read_only); for (int x = 0; x <size; x ++) {stmt.addbatch ( "adlogs에 삽입 (ip, 웹 사이트, yyyymmdd, hour, object_id) 값 ( '192.168.1.3', 'localhost', '20081009', 8, '23123'); } stmt.executebatch (); conn.commit ();방법 3 : 직접 진술을 사용하십시오
conn.setAutocommit (false); Statement stmt = conn.createstatement (resultset.type_scroll_sensitive, resultet.concur_read_only); for (int x = 0; x <size; x ++) {stmt.execute ( "adlogs에 삽입 (ip, 웹 사이트, yyyymmdd, hour, object_id) 값 ( '192.168.1.3', 'localhost', '20081009', 8, '23123'); } conn.commit (); 위의 방법을 사용하여 10 만 조각의 데이터를 삽입하는 평균 테스트 시간은 다음과 같습니다.
방법 1 : 17.844S
방법 2 : 18.421S
방법 3 : 16.359s
JDBC 배치 명령문의 삽입은 성능을 향상시킬뿐만 아니라 배치를 사용하지 않을 때보 다 느린다는 것을 알 수 있습니다. 물론 이것은 JDBC의 특정 드라이버의 구현 방법과 관련이있을 수 있습니다. 첨부 파일은 내 컴퓨터에서 실행하는 데 사용할 수있는 테스트 코드입니다.
배치 삽입을 수행 할 때 가장 중요한 것은 제출을 자동으로 취소하는 것이므로 JDBC의 배치 구문이 사용되는지 여부는 중요하지 않습니다.
conn.setAutocommit (false)
나는 개인적으로 첫 번째 방법이 가장 편리하고 실용적이라고 생각합니다.
JDBC 배치 삽입 데이터의 예 :
최근에 Excel 데이터를 데이터베이스로 가져 오기 위해 프로그램을 진행할 때 많은 양의 데이터로 인해 JDBC 배치 삽입을 사용할 준비를하고있었습니다. 따라서 reparestatement.addbatch ()가 사용됩니다. 1W 데이터가 추가되면 삽입 작업이 수행되고 ProadeCutebatch ()가 사용됩니다. 나는 이것이 빠를 것이라고 생각했지만 65,536 개의 데이터를 삽입하는 데 30 분 이상 걸렸습니다. 그래서 동료들에게 이런 종류의 대규모 데이터 수입을 어떻게 처리했는지 물었습니다. 나는 또한 JDBC 배치 삽입 처리를 사용했다는 것을 알았지 만 나와 달리 Con.setAutocommit (false)를 사용했습니다. 그런 다음 proadestatement.executebatch () 다음 con.commit ()를 실행했습니다. 그래서 다시 시도했습니다. 기적은 무엇입니까? 이 데이터를 가져 오는 데 30 분이 걸렸 으며이 두 문장을 추가 한 후 완료하는 데 15 초 밖에 걸리지 않았습니다. 그래서 그 이유를 확인하고 온라인에서 다음과 같은 설명을 찾았습니다.
* InnoDB로 데이터를 가져 오면 MySQL이 자동 커밋 모드가 활성화되어 있지 않은지 확인하십시오.
모든 인서트마다 디스크로 로그 플러시가 필요합니다. 가져 오기 작업 중에 자동 커밋을 비활성화하려면
자동 커밋 및 커밋 진술을 설정하십시오.
AutoCommit = 0을 설정합니다.
... SQL 가져 오기 진술 ...
저지르다;
처음으로, 그것은 setAutocommit (false)가 없기 때문입니다. 각 삽입 문에 대해 로그가 디스크에 생성됩니다. 따라서 배치 인서트가 설정되어 있지만 효과는 단일 삽입과 같아서 삽입이 매우 느립니다.
일부 코드는 다음과 같습니다.
문자열 sql = "테이블에 삽입 *****"; con.setAutocommit (false); ps = con.preparestatement (sql); for (int i = 1; i <65536; i ++) {ps.addbatch (); // if (i % 100000 == 0) {ps.ExecuteBatch (); con.commit (); }} // 1W 미만의 삽입 데이터 ps.ExecuteBatch (); con.commit ();위는 단지 반찬 일뿐입니다. 그런 다음 "서빙"다음에 다음과 같습니다.
1. 테스트 배치 쓰기 데이터
Long Start = System.CurrentTimeMillis (); daorecord daorecord = 새로운 daorecord (); 목록 <t> list = new ArrayList <t> (); for (int i = 1; i <= 1000; i ++) {for (int j = 1; j <= 1000; j ++) {t t = new t (); T.seti (i); T. 세트 (J); list.add (t); }} daorecord.insertbatch (목록); System.out.println ( "시간 소모 :" + (System.CurrentTimeMillis () -Start) + "MS"); 2. 배치 쓰기 데이터 테스트
public void insertbatch (list <t> list) {string sql = "t (go, back) 값 (?,?)에 삽입"; DBHELPER DBH = NEW DBHELPER (SQL); 연결 conn = dbh.returnconn (); try {conn.setautocommit (false); //이 문장은 false 여야한다는 점에 유의하십시오. 첫 번째 참조 propertatement ps = conn.preparestatement (sql); for (int i = 0; i <list.size (); i ++) {ps.setint (1, list.get (i) .geti ()); ps.setint (2, list.get (i) .getj ()); ps.addbatch (); if (i % 10000 == 0) {ps.Executebatch (); conn.commit (); }} ps.ExecuteBatch (); conn.commit (); conn.close (); } catch (sqlexception e) {// todo 자동으로 생성 된 캐치 블록 e.printstacktrace (); }}데이터 테이블 :
실험 결과 :
위의 내용은이 기사에 관한 모든 것입니다. 모든 사람의 학습에 도움이되기를 바랍니다.