그래서 EMF/Texo 조합을 사용하여 생성되고 주석 처리 된 많은 수의 클래스가 있습니다. JPA/Eclipselink를 사용하여 SQL Server 데이터베이스에 저장합니다.JPA/Eclipselink/Texo의 대량 삽입이 순수 JDBC 삽입보다 속도가 느린 이유는 무엇입니까?
많은 수의 개체를 유지해야 할 때 성능이 저하됩니다. 따라서 프레임 워크 (foo)와 일반 JDBC 대량 삽입 (bar)을 사용하여 대량 삽입의 성능을 비교하는 두 개의 테스트 케이스 (TestBulkInserts.java 참조)를 작성했습니다.
평균 크기 미만의 대량 삽입물 인 10000 개의 개체를 삽입 할 때. foo는()과 바()주고 다음 시간 :
, 독일 - 기간 JPA/TEXO는 : 같은 큰 차이가 왜 궁금하네요 892ms
(:
, 독일 - 기간 일반 JDBC를 19.620ms 더 많은 요인 20!). 크기가 커지면 악화됩니다.
DatabaseObject 클래스는 PersistableObjectClass.java (아래 참조)를 확장하며 Texo + EMF를 사용하여 (각각의 DAO 클래스를 포함하여) 생성됩니다.
필요한 연결 세부 정보를 제외하고 persistence.xml에 특정 설정을 추가하지 않았습니다.
TestBulkInserts.java :
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
...
import com.ownproject.loader.generated.DbModelPackage;
import com.ownproject.loader.DatabaseObject;
import com.ownproject.loader.dao.DatabaseObjectDao;
import javax.persistence.Persistence;
import org.eclipse.emf.texo.server.store.EntityManagerProvider;
import org.junit.Test;
public class TestBulkInserts {
private static final int NUM_LOOPS = 10000;
@Test
public void foo() {
TestMethods.connectTestDBandEMF();
// basically does this
// DbModelPackage.initialize();
// EntityManagerProvider.getInstance().setEntityManagerFactory(Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_TEST));
Stopwatch sw = Stopwatch.createStarted();
DatabaseObjectDao dao = new DatabaseObjectDao();
dao.getEntityManager().getTransaction().begin();
for (int i = 0; i < NUM_LOOPS; i++) {
DatabaseObject dbo = new DatabaseObject();
dbo.setString(UUID.randomUUID().toString());
dbo.setInsert_time(Date.valueOf(LocalDate.now()));
dao.insert(dbo);
}
dao.getEntityManager().getTransaction().commit();
sw.stop();
System.out.println(String.format("Duration JPA/Texo: %,dms", sw.elapsed(TimeUnit.MILLISECONDS)));
}
@Test
public void bar() throws ClassNotFoundException, SQLException {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
String connectionUrl = "jdbc:sqlserver://hostname:1433;databaseName=local_test;user=sa;password=blablub;";
Connection con = DriverManager.getConnection(connectionUrl);
con.setAutoCommit(false);
Stopwatch sw = Stopwatch.createStarted();
PreparedStatement insertStatement = con.prepareStatement("INSERT INTO DatabaseObject(b_id, insert_time) VALUES (?, ?)");
for (int i = 0; i < NUM_LOOPS; i++) {
insertStatement.setString(1, UUID.randomUUID().toString());
insertStatement.setDate(2, Date.valueOf(LocalDate.now()));
insertStatement.addBatch();
}
insertStatement.executeBatch();
con.commit();
con.close();
sw.stop();
System.out.println(String.format("Duration plain JDBC: %,dms", sw.elapsed(TimeUnit.MILLISECONDS)));
}
}
PersistableObjectClass.java :
import javax.persistence.Basic;
...
import javax.persistence.TemporalType;
@Entity(name = "PersistableObjectClass")
@MappedSuperclass()
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class PersistableObjectClass {
@Basic()
@Temporal(TemporalType.TIMESTAMP)
private Date insert_time = null;
@Id()
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int s_id = 0;
...
}
가주의 깊게 읽기 :
그래서,이처럼 배치 작업이 보일 것입니다 방법입니다 배치 세션 배치 – zloster
힌트에 감사드립니다! 기억에 문제가 있니? 플러싱이 로딩 시간을 감소시키지 않았기 때문에. – KayleeTheMech
JPA는 오버 헤드를 추가하기 때문에 약간의 차이가있을 것으로 예상되지만 숫자를 설명하기에는 너무 많은 변수가 있습니다. 당신은 정말로 당신이 사과를 비교하기 위해 사과를 만들고 있는지 확인하기 위해 생성 된 SQL을보기 위해 로그인을 사용 했습니까? JPA/EclipseLink에서 사용하는 설정은 무엇입니까? 배치 크기와 일치하는 사전 할당을 허용하는 대신 시퀀스 관리에 Identity를 사용하는 이유는 무엇입니까? – Chris