2

我有 2 个数据库old& newold数据库详细信息需要过滤/操作并存储到new.

OLD DB

  1. 我有大约 10000 个配置(数据库行)

  2. 和 10000 个 BLOBS(xml 文件大小平均为 4MB)匹配上面的配置 ID

NEW DB

  1. 1 个新表将包含旧表中的过滤数据,但这次没有 BLOB 数据,而是绝对路径

  2. 并根据配置提供一些建议

在这里,我编写了一个程序(对 DB 使用 Groovy 和 MyBatis),它获取所有可用的配置记录OLD DB并存储在类列表中,并且 DB 连接已关闭

为了也为每个配置 id 获取 BLOBS,建立一个新连接并保持打开很长时间

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 DB。这是一种好的做法,还是我需要NEW 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 分钟。我认为您将希望节省 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

于 2012-11-14T07:30:23.453 回答