限制 ADO 记录集的内存使用

Limiting memory-usage of ADO recordset

我正在使用 ADO (C++) 连接到数据库,我正在读取 table 大约 500 万条记录,我想限制客户端的内存使用。目前,遍历记录会导致进程内存增加大约 1GB,我想显着减少它。

代码是非常标准的 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。

我想做的是:在处理的同时,告诉记录集释放已经处理过的记录的内存,使内存使用率保持在较低水平。有执行此操作的功能吗?

如果没有,我可以采用手动方法对具有多个记录集的数据进行分区,并在使用时释放它们吗?

我的解决方案是手动释放数据。每 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();
    }
}

不像记录集释放内存那样优雅,但似乎有效。