VC ADO 更新100万条记录,时间好慢!

时间:2021-05-08 23:20:57
有一个test表,含有100万左右的个人记录,于是我首先将这个表的数据select ksh,score from table之后 
struct OMR_INFO 
{
char ksh[100];
double score;
};

typedef CArray<OMR_INFO,OMR_INFO&> CArrayOMR;

转为了一个CArrayOMR,
然后将数据进行处理,根据已有的数据内容,经过处理获得了新数据。
然后我把这含有了100万条的CArrayOMR更新到table表里面, 我发现如果我只选择1万条进行处理 (select TOP 20000 from table), 时间还可以接受, 20几秒钟就完成了。 如果我一次性都选择(select * from table)就发现速度非常非常的慢。半个多小时也出不来结果。
我搜索了一些帖子,有一些人说可以利用批量 分页什么的思想解决。不知各位是否有过类似的经验呢?
描述的代码我简单的写一下:
CArrayOMR arrayomrinfo;
OMR_INFO omrinfo;
CString omr,ksh;
m_pRecordset = m_pConnection->Execute((_bstr_t)"select * from table",&RecordsAffected,adCmdText);
while (!m_pRecordset->adoEOF)
{
      var = m_pRecordset->GetCollect("theomr");
      if (var.vt != VT_NULL)
     {
omr = (LPCTSTR)_bstr_t(var);
      }
     else
     {
omr = "";
      }

      var = m_pRecordset->GetCollect("theksh");
      if (var.vt != VT_NULL)
      {
ksh = (LPCTSTR)_bstr_t(var);
      }
      OMR_INFO omrinfo;
      omr.TrimLeft(' ');
      omr.TrimRight(' ');
      double score = 0;
      score = CalcuOmr(omr);//计算分数
      omrinfo.score = score;
      strcpy(omrinfo.ksh,ksh);
      arrayomrinfo.Add(omrinfo);
      m_pRecordset->MoveNext();
}

for (int j=0;j<arrayomrinfo.GetSize();j++)
{
    double score=0;
    CString omr;
    strupdate.Format("update %s set %s=%.2f where theksh='%s' and thekmh='%   s'",theTablefield,theScorefield,arrayomrinfo[j].score,arrayomrinfo[j].ksh,kmh);
    try
    {
        theApp.m_pConnection->Execute((_bstr_t)strupdate,&RecordsAffected,adCmdText);
     }
     catch(_com_error *e)
    {
        AfxMessageBox(e->Description());
        return ;
    }
    CString index;
    index.Format("已处理%d条",j+1);
    ((CStatic*)GetDlgItem(IDC_PROCESS_STATIC))->SetWindowText(index);
    m_nStep = m_nStep +1;
    pProgCtrl1->StepIt();
    pProgCtrl1->SetPos(m_nStep);
}

8 个解决方案

#1


1w条20几秒,100w条就是2000多秒。3600秒是一小时。你看着办吧。
建议开线程。

#2


那能给点具体的建议吗?

#3


1W条20几秒。。。还容易接受。。。太慢了!
typedef CArray<OMR_INFO,OMR_INFO&> CArrayOMR;
这玩意很慢的,你直接开数组好了

#4


((CStatic*)GetDlgItem(IDC_PROCESS_STATIC))->SetWindowText(index);
 这玩意也慢!在大量数据里少用!用进度条比这快

#5


多线程处理

#6


其实这类东西 批量更新的方法是UpdateBatch

但是100万依然很慢

多线程做同一个表的更新或添加并发好的选择,因为数据库本身有互斥锁

还有可以拼接一个sql 语句比如说"update xxx set xx=2 update xxx set xx=3"


数据库如果是sql server的话,似乎可以用一句sql 搞定,而不必写这么多代码

#7


有规则的数据更新,应该让存储过程去做

那么大量的记录,一次性处理是不恰当的(服务器、客户端的资源紧张,会使程序运行效率大降)
使用线程,一次1000条来处理,整个进度条,用户可以终止进程,在记录中整个时间戳什么的,方便控制

#8


谢谢!大家的建议?我会一一测试各种方法的

#1


1w条20几秒,100w条就是2000多秒。3600秒是一小时。你看着办吧。
建议开线程。

#2


那能给点具体的建议吗?

#3


1W条20几秒。。。还容易接受。。。太慢了!
typedef CArray<OMR_INFO,OMR_INFO&> CArrayOMR;
这玩意很慢的,你直接开数组好了

#4


((CStatic*)GetDlgItem(IDC_PROCESS_STATIC))->SetWindowText(index);
 这玩意也慢!在大量数据里少用!用进度条比这快

#5


多线程处理

#6


其实这类东西 批量更新的方法是UpdateBatch

但是100万依然很慢

多线程做同一个表的更新或添加并发好的选择,因为数据库本身有互斥锁

还有可以拼接一个sql 语句比如说"update xxx set xx=2 update xxx set xx=3"


数据库如果是sql server的话,似乎可以用一句sql 搞定,而不必写这么多代码

#7


有规则的数据更新,应该让存储过程去做

那么大量的记录,一次性处理是不恰当的(服务器、客户端的资源紧张,会使程序运行效率大降)
使用线程,一次1000条来处理,整个进度条,用户可以终止进程,在记录中整个时间戳什么的,方便控制

#8


谢谢!大家的建议?我会一一测试各种方法的