[英]How to improve the performance of DB import using JDBC?
我正在從CSV文件中將大量數據導入MSSQL Server2008。我正在使用核心JDBC(沒有任何ORM框架),並使用Microsoft提供的驅動程序“ sqljdbc4.jar”與DB通信。
以下是我的要求:
截至目前,正在逐一導入記錄。 即使正在使用PreparedStatement,也要花費大量時間。
我沒有使用批量導入,因為我需要將確切的錯誤記錄到錯誤文件中。
請提出一個在不犧牲准確的錯誤記錄的情況下提高性能的想法。 而且我被迫在沒有任何ORM工具的情況下執行此操作。
這是示例代碼:
for (Map<String, String> csvRecord : csvAsList) {
// Prepare category object using csvRecord.
// invoke obj.insert(category);
}
public Category insert(Category category){
if (category == null) {
return null;
}
String SQL = "INSERT INTO t1(c1,c2) VALUES(?,?)";
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
pstmt = this.dbConnectionUtil.getConnection().prepareStatement(SQL,
Statement.RETURN_GENERATED_KEYS);
pstmt.setInt(1, category.getField1());
pstmt.setString(2, category.getField2());
int result = pstmt.executeUpdate();
if (result < 1) {
return null;
}
rs = pstmt.getGeneratedKeys();
if (rs.next()) {
category.setId(rs.getInt(1));
}
} finally {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
this.dbConnectionUtil.closeConnection();
}
return category;
}
2012年9月20日更新。
我已經修改了代碼,以便導入一個CSV文件,將只創建一個PreparedStatement對象。 新代碼如下:
public void importCSV(){
// Create a db connection if its null or closed.
// Create PreparedStatement objects for selects and inserts if null or closed.
for (Map<String, String> csvRecord : csvAsList) {
// Prepare category object using csvRecord.
// Check whether category exists in by.
// Import files can have up to 1,00,000 records so tracking errors is critical.
try{
categoryDAO.findByName(categoryName,<PreparedStatement object>);
}
catch(Exception exp){
// log this to error.csv file
}
// If its a new category import it to the db.
try{
categoryDAO.insert(category,<PreparedStatement object>);
}
catch(Exception exp){
// log this to error.csv file
}
}
// Close PreparedStatement objects
// Close DB Connection
}
public Category insert(Category category,PreparedStatement pstmt ) throws SQLException{
if (category == null) {
return null;
}
ResultSet rs = null;
try {
pstmt.setInt(1, category.getField1());
pstmt.setString(2, category.getField2());
int result = pstmt.executeUpdate();
if (result < 1) {
return null;
}
rs = pstmt.getGeneratedKeys();
if (rs.next()) {
category.setId(rs.getInt(1));
}
} finally {
if (rs != null)
rs.close();
}
return category;
}
謝謝。
似乎您正在為輸入數據的每一行再次調用prepareStatement
。 這幾乎可以消除使用PreparedStatement
獲得的性能提升。 而是在循環外部創建PreparedStatement
,並在循環內部僅保留setInt
, setString
和executeUpdate
調用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.