由于数据量大,直接读Access数据库,速度跟不上,则将表读到Sqlite中。
直接从Aceess中读一条,写一条,很慢,6000条数据写了30多分钟。通过sqlite3_prepare_v2方法,稍能提高,但效果不明显。
class DatabaSEOperate { private: _ConnectionPtr m_pConnection; _RecordsetPtr m_pRecordset; _variant_t var; _variant_t RecordsAffected; std::string name[2]; std::string block[2]; public: int init() { CoInitialize(NULL); m_pConnection.CreateInstance(__uuidof(Connection)); m_pRecordset.CreateInstance(__uuidof(Recordset)); try { m_pConnection->Open(getPath().c_str(),"",adModeUnknown); return 1; } catch(_com_error e) { //cout<<"数据库连接失败,确认数据库db1.mdb是否在当前路径下!"<<endl; return -1; } } int AcsToSql() { try { std::string sql= "select * from nodeconnect"; m_pRecordset->Open(sql.c_str(), m_pConnection.GetInterfacePtr(), adOpenDynamic, adLockOptimistic, adCmdText); if(!m_pRecordset->BOF) { m_pRecordset->MoveFirst(); float index=0; sqlite3_stmt* stmt3 = NULL; char* cErrMsg; sqlite3_exec(pDB,"begin;",&cErrMsg); int ret = sqlite3_prepare_v2(pDB,"insert into NCN(FN,AN,ALEN,CBL) values(?,?,?)",-1,&stmt3,NULL); if(ret != SQLITE_OK) { if(stmt3) { sqlite3_finalize(stmt3); } m_pRecordset->Close(); m_pRecordset = NULL; return 0; } while(!m_pRecordset->adoEOF) { var=m_pRecordset->GetCollect("fnode"); std::string fnode=_com_util::ConvertBSTRToString((_bstr_t)var); var=m_pRecordset->GetCollect("fsname"); std::string cable=_com_util::ConvertBSTRToString((_bstr_t)var); var=m_pRecordset->GetCollect("snode"); std::string snode=_com_util::ConvertBSTRToString((_bstr_t)var); var=m_pRecordset->GetCollect("nodelen"); std::string len=_com_util::ConvertBSTRToString((_bstr_t)var); /* string strSql = ""; strSql += "insert into NCN(FN,CBL)"; strSql += "values('"; strSql += fnode; strSql += "','"; strSql += snode; strSql += "','"; strSql += len; strSql += "','"; strSql += cable; strSql += "');"; cout<<"Now: "<<strSql<<endl; */ sqlite3_bind_text(stmt3,1,fnode.c_str(),strlen(fnode.c_str()),NULL); sqlite3_bind_text(stmt3,2,snode.c_str(),strlen(snode.c_str()),3,len.c_str(),strlen(len.c_str()),4,cable.c_str(),strlen(cable.c_str()),NULL); if(sqlite3_step(stmt3) != SQLITE_DONE) { cout<<"insert fail: "<<endl; } /*char* cErrMsg; int nRes = sqlite3_exec(pDB,strSql.c_str(),&cErrMsg); if (nRes != SQLITE_OK) { cout<<"add user fail: "<<cErrMsg<<endl; }*/ index=index+1; cout<<"Now: "<<index<<endl; sqlite3_reset(stmt3); m_pRecordset->MoveNext(); } sqlite3_finalize(stmt3); sqlite3_exec(pDB,"commit;",&cErrMsg); m_pRecordset->Close(); m_pRecordset = NULL; return 1; } else { m_pRecordset->Close(); m_pRecordset = NULL; return 0; } } catch(_com_error e) { m_pRecordset->Close(); m_pRecordset = NULL; return -1; } } void conClose() { if(m_pConnection->State) { m_pConnection->Close(); m_pConnection= NULL; m_pRecordset = NULL; } } };
原因在sqlite3 insert into 等操作时它是已文件的形式存在磁盘中,每次访问时都要打开一次文件,如果对数据库进行大量的操作,那时很慢。
解决办法用事务的形式提交:因为我们开始事务后,进行的大量操作的语句都保存在内存中,当提交时才全部写入数据库,此时,数据库文件也就只用打开一次。
在进行大量的操作前使用如下语句:
rc = sqlite3_exec(db,&szErrMsg);
for (...)
{
//insert into operate
}
rc = sqlite3_exec(db,&szErrMsg);
这样速度提高了一百多倍,6000多条数据能在2分钟内完成! (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|