2017-02-24 59 views
0

我正在使用ADO(C++)连接到数据库,我正在读取一个大约5m记录的表,并且我想限制客户端上的内存使用情况。目前,遍历记录会导致进程内存增加1GB,并且我希望显着减少这些内存。限制ADO记录集的内存使用情况

的代码是非常标准的C++ ADO(编辑的可读性):

ADODB::_ConnectionPtr m_pConnection; 
m_pConnection.CreateInstance(__uuidof(ADODB::Connection)); 
m_pConnection->Open(_bstr_t(strConnect), m_strDBUserName, m_strDBPassword, -1); 

ADODB::_RecordsetPtr pRecordSet; 
pRecordSet.CreateInstance(__uuidof(ADODB::Recordset)); 

pRecordSet->putref_ActiveConnection(pConnection); 
pRecordSet->Open(_variant_t(bstrQuery), vNull, ADODB::adOpenForwardOnly, ADODB::adLockOptimistic, ADODB::adCmdText); 

pRecordSet->MoveFirst(); 
while(!pRecordSet->EOF) 
{ 
    CString cardNum = (LPCWSTR)(pRecordSet->Fields->GetItem("CARD_NUM")->Value.bstrVal); 
    int nSeqNum = pRecordSet->Fields->GetItem("SEQ_NUM")->Value.intVal; 

    // process data 

    pRecordSet->MoveNext(); 
} 

我观察的是,因为它通过记录遍历线,内存使用量的增加,每百万条记录约200MB。

我想要做的是:while,处理,告诉记录集以释放已处理记录的内存,以便内存使用率保持较低。有没有这样做的功能?

如果不是,我可以采取手动的方法来分区数据与多个记录集,释放他们,因为我去?

回答

0

我的解决方案是手动释放数据。每N条记录,我关闭记录集,并从下一条记录开始执行新的查询。这需要一些改变,我的疑问...

int partitionSize = 100000, nRecordIndex = 0; 
CString query("select CARD_NUM, SEQ_NUM from CMS_CARD order by CARD_NUM, SEQ_NUM"); 
DoSelect(theCWIDatabaseManager.GetConnection(), pRecordSet, query); 
pRecordSet->MoveFirst(); 

while(!pRecordSet->EOF) 
{ 
    // process data 

    nRecordIndex++; 
    if(nRecordIndex % partitionSize == 0) 
    { 
     pRecordSet->Close(); 
     query.Format("select CARD_NUM, SEQ_NUM from CMS_CARD where CARD_NUM = '%s' and SEQ_NUM > '%s' union select CARD_NUM, SEQ_NUM from CMS_CARD where CARD_NUM > '%s' order by CARD_NUM, SEQ_NUM", lastCardNum, lastSeqNum, lastCardNum); 
     DoSelect(theCWIDatabaseManager.GetConnection(), pRecordSet, query); 
     pRecordSet->MoveFirst(); 
    } 
} 

不一样优雅,仿佛记录集释放的内存,但似乎工作。