2012-11-14 22 views
2

我有2個數據庫old & new,old數據庫細節需要過濾/操縱並存儲到new在過程完成之前打開新的數據庫連接或保持連接處於打開狀態很好嗎?

OLD DB

  1. 我有大約10000配置(DB行)

  2. 和10000 BLOBS(XML文件的大小是4MB上的平均值)匹配配置ID的從上方

NEW DB

  1. 是將包含來自舊過濾後的數據

    1新表,但這次沒有BLOB數據,而不是絕對路徑

  2. 和每個配置一些建議

這裏我寫了一個程序(使用Groovy & MyBatis for DB),它可以獲得OLD DB中的所有配置記錄,並存儲在類的列表和數據庫連接被關閉

爲了得取的斑每個配置ID,一個新的連接建立&保持打開很長一段時間

List<String> projectid 
List<CSMConfigInfo> oldConfigs 
List<ConfigInfo> newConfigs 
Map<String,CSMConfigInfo> oldConfigMap 

SqlSession session = DatabaseConnectivity.getOldCSMDBSessionFactory().openSession() 
/* trying to batch execute based on project id */ 
    projectid.each {pid-> 
     logger.info "Initiating conversion for all configuration under $pid project id" 
     oldConfigMap.each {k,v-> 
/* Here I am keeping a DB connection open for a long time */   
      if(pid.equals(v)){     
       createFromBlob(k,session)     
      } 
     }      
     logger.info "Completed for $pid project id\n"   
    } 

session.close() 

獲取的BLOB後1乘1,我創建一個臨時的xml文件,該文件被解析爲應用過濾器插入NEW DB。在下面的代碼中,您可以看到基於xml是否可轉換和可分析,爲NEW DB打開了一個新連接。這是好的做法還是我需要保持打開所有10000條記錄的NEW DB連接?

/* XML is converted to new format and is parsable */ 
def createFromBlob(CSMConfigInfo cfg,SqlSession oldCSMSession){ 
    . 
    . 

    if(xmlConverted&&xmlParsed){ 
     //DB Entries 
     try{ 
      /* So now here I am opening a new connection for every old config record, which can be 10000 times too, depending on the filter */ 
      SqlSession sess = DatabaseConnectivity.getNewCSMSessionFactory().openSession() 

      //New CSM Config 
      makeDatabaseEntriesForConfiguration(newConfig,sess) 
      //Fire Rules 
      fireRules(newConfig,sess,newCSMRoot) 

      sess.close() 

     } 
     catch(IOException e){ 
      logger.info "Exception with ${newConfig.getCfgId().toString()} while making DB entries for CONFIG_INFO" 
     } 
     logger.info "Config id: "+cfg.getCfgId().toString()+" completed successfully, took "+getElapsedTime(startTime)+ " time. $newabspath" 
    } 
    else{ 
     def errormsg = null 
     if(!xmlConverted&&!xmlParsed) 
      errormsg = "Error while CONVERSION & PARSING of config id "+cfg.getCfgId().toString()+", took "+getElapsedTime(startTime)+ " time." 
     else if(!xmlConverted) 
      errormsg = "Error while CONVERSION of config id "+cfg.getCfgId().toString()+", took "+getElapsedTime(startTime)+ " time." 
     else if(!xmlParsed) 
      errormsg = "Error while PARSING of config id "+cfg.getCfgId().toString()+", took "+getElapsedTime(startTime)+ " time." 
     logger.info errormsg 
    } 

    makeDatabaseEntriesForConvertStatus(csmConfigConvertStatus,oldCSMSession) 
} 

這目前適用於20條記錄,但我不知道它將如何反應所有10000條記錄。請幫助

更新

我會針對每個配置

回答

4

它總是會更有效地使用池的數據庫連接,讓容器在需要時管理建立和關閉連接。創建一個連接,執行你的語句,然後關閉這個連接,可以避免使用一個池,它在給你連接使用之前會預連接,在大多數情況下(你所描述的細節)連接不需要給定它可能已經連接。

因此,是保持連接打開,甚至更好地連接您的連接更有效...

+0

感謝您的回覆。 MyBatis不關心連接池?你知道我可以關注數據庫連接池的任何資源嗎? – abi1964

+0

我會查看http://grails.org/plugin/jdbc-pool,以達到您的要求。或者,您可以自己創建多個連接,並且不要關閉它們直到代碼完成所需的任何操作... – ramsinb

+0

MyBatis連接池的任何資源。我沒有使用Grails :( – abi1964

2

約3-6秒從我的經驗來看,通常是一個開銷,當你創建一個循環的每個週期內一個新的連接。如果打開連接需要0.1秒,那麼對於10000條記錄,您的時間開銷將爲1,000秒(即大約17分鐘)。如果在超過10,000條記錄時保持連接處於打開狀態而不關閉,則可節省17分鐘時間。我想你會想要節省17分鐘以及關閉和重新創建連接10,000次所需的CPU資源。打開循環外的連接,並在循環後關閉它。

嘗試修改方法createFromBlob,以便它會接受這樣的兩個會話;

def createFromBlob(CSMConfigInfo cfg,SqlSession oldCSMSession, SqlSession newCSMSession){

然後更換該代碼塊;

 /* So now here I am opening a new connection for every old config record, which can be 10000 times too, depending on the filter */ 
     SqlSession sess = DatabaseConnectivity.getNewCSMSessionFactory().openSession() 

     //New CSM Config 
     makeDatabaseEntriesForConfiguration(newConfig,sess) 
     //Fire Rules 
     fireRules(newConfig,sess,newCSMRoot) 

     sess.close() 

有了這個;

//New CSM Config 
     makeDatabaseEntriesForConfiguration(newConfig,newCSMSession) 
     //Fire Rules 
     fireRules(newConfig,newCSMSession,newCSMRoot) 

然後,你必須創建傳給你開始循環就在接近新的SqlSession,並將它傳遞給你修改的方法(createFromBlob

+0

感謝您的回覆。每個記錄通常需要大約5秒 – abi1964

+0

不客氣。在兩個循環外部創建兩個連接並保持活動狀態。那應該在'projectid.each {pid->'這一行之前。這應該可以爲你節省開銷。如果有幫助,可以將我的答案標記爲正確答案;) – mwangi

+0

如果5秒,那麼因爲此答案表示連接池將會更好,因此您沒有關於數據庫中CLOB或其他複雜類型的操作。 – OQJF

相關問題