2

2 つのデータベースold&があります。データベースの詳細をフィルタリング/操作して、に保存する必要があります。newoldnew

OLD DB

  1. 約10000の構成(DB行)があります

  2. 上記の構成 ID に一致する 10000 BLOB (xml ファイルのサイズは平均で 4 MB)

NEW DB

  1. 古いものからフィルタリングされたデータを含む新しいテーブルが 1 つあるが、今回は BLOB データではなく、絶対パスの代わりに

  2. および構成ごとにいくつかの推奨事項

OLD DBここで、使用可能なすべての構成レコードを取得してクラスのリストに保存し、DB 接続を閉じるプログラムを (DB に Groovy と MyBatis を使用して) 作成しました。

各構成 ID の BLOB も取得するために、新しい接続が確立され、長時間開いたままになります

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 つずつフェッチした後、一時 xml ファイルを作成し、これを解析して に挿入するためのフィルターを適用しますNEW DB。以下のコードでは、xml が変換可能で解析可能かどうかに基づいて、新しい接続が開かれていることがわかりますNEW DBNEW DBこれは良い習慣ですか、それとも 10000 レコードすべてに対して接続を開いたままにしておく必要がありますか?

/* 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 レコードすべてに対してどのように反応するかはわかりません。助けてください

アップデート

設定ごとに約 3 ~ 6 秒かかります

4

2 に答える 2

5

データベース接続のプールを使用する方が常に効率的であり、必要に応じてコンテナーがその接続の確立と終了を管理できるようにします。接続を作成し、ステートメントを実行してからその接続を閉じることは、使用する接続を提供する前に事前に接続するプールを使用して回避できます。ほとんどの場合 (特に説明した内容について) 接続を確立する必要はありません。すでに接続されている可能性があります。

したがって、はい、接続を開いたままにしておく方が効率的であり、接続をプールする方がさらに効果的です...

于 2012-11-14T07:38:35.320 に答える
2

私の経験から、ループの各サイクル内で新しい接続を作成すると、通常はオーバーヘッドが発生します。接続を開くのに 0.1 秒かかる場合、10000 レコードの場合、時間オーバーヘッドは 1,000 秒 (約 17 分) になります。接続を開いたままにして、10,000 レコードを超えるまで接続を閉じなかった場合、17 分節約できます。接続を 10,000 回閉じて再作成するのに必要な CPU リソースだけでなく、17 分間も節約したいと思うでしょう。ループの外側で接続を開き、ループの後に閉じます。

createFromBlobこのような 2 つのセッションを受け入れるようにメソッドを変更してみてください。

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)

于 2012-11-14T07:30:23.453 に答える