使用ADO的Next函数对数据集遍历越来越慢

c1aud 2008-03-28 05:23:22
使用的数据库是Microsoft SQL Server 2000
使用编译器是C++ Builder 6
我有如下一段代码
#include <mmsystem.h>

TADOQuery* ADOQuery1;
.....
DWORD startTime = ::timeGetTime();
ADOQuery1->Close();
ADOQuery1->SQL->Text = "select [MsgId],[MsgText] from MsgInfo";
ADOQuery1->Open();

DWORD time2 = (::timeGetTime()-startTime)/1000;
AnsiString strLog;
strLog.sprintf("Loaded MsgInfo from Database, count: %d, time cost: %d", ADOQuery1->RecordCount, time2);
PrintLog(str1);

int t = 0;
ADOQuery1->First();
startTime = ::timeGetTime();
while( !ADOQuery1->Eof )
{
t++;
if( !(t%5000) )
{
time2 = (::timeGetTime()-startTime)/1000;
strLog.sprintf("Loading MsgInfo from Recordset, time cost: %d", time2);
PrintLog(str2);
}
ADOQuery1->Next();
}
time2 = (::timeGetTime()-startTime)/1000;
strLog.sprintf("Loaded MsgInfo from Recordset, time cost: %d", time2);
PrintLog(str2);

执行后获得如下日志
Loaded MsgInfo from Database, count: 41503, time cost: 1

Loading MsgInfo from Recordset, time cost: 1
Loading MsgInfo from Recordset, time cost: 3
Loading MsgInfo from Recordset, time cost: 5
Loading MsgInfo from Recordset, time cost: 8
Loading MsgInfo from Recordset, time cost: 12
Loading MsgInfo from Recordset, time cost: 17
Loading MsgInfo from Recordset, time cost: 22
Loading MsgInfo from Recordset, time cost: 28
Loading MsgInfo from Recordset, time cost: 34
Loading MsgInfo from Recordset, time cost: 42

Loaded MsgInfo from Recordset, time cost: 45

为什么Next访问速度会越来越慢?
我查了CSDN之前有个类似的问题,但是没有找到答案,请大侠帮忙看看。
http://topic.csdn.net/t/20031114/17/2461467.html
...全文
392 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
c1aud 2009-06-14
  • 打赏
  • 举报
回复
调用 DisableControls 即可
castlooo 2008-04-17
  • 打赏
  • 举报
回复
EOF慢
吴丁 2008-04-15
  • 打赏
  • 举报
回复
不是Next慢,而是Eof判断很慢,你测试下就知道了。我是这样做的,办法是笨了点,但效果立马可见·简单令人发指!

unsigned int count;
ADOQuery1->SQL->Text = "select count(*) as count from (select [MsgId],[MsgText] from MsgInfo) ";
ADOQuery1->Open();
count =ADOQuery1->FieldByName("count")->AsInteger;
ADOQuery1->SQL->Text = "select [MsgId],[MsgText] from MsgInfo ";
ADOQuery1->Open();
ADOQuery1->First();
for(unsigned int i=0; i <count; i++)
{
.....
ADOQuery1->Next();
}
效果很明显,你试下就知道了。
sfengnet 2008-04-10
  • 打赏
  • 举报
回复
楼上的,你的计时单位是什么?

我觉得差别很小啊
CACACACACA 2008-04-05
  • 打赏
  • 举报
回复
End Time: 21200
End Time: 11146

End Time: 21882
End Time: 10565

200多万记录. 上面是没有设置的, 下面是设置后的。
CACACACACA 2008-04-05
  • 打赏
  • 举报
回复
CacheSize 设大点 1000
Prepared 设为 True;
LockType 设为 ltReadOnly
CursorType 设为 ctOpenForwardOnly

另外. First之前先.
ADOQuery1.DisableControls;
最后
ADOQuery1.EnableControls;

我用两个ADOQuery测试,平均有一倍差距。
海嵌 2008-04-05
  • 打赏
  • 举报
回复
顶起
sfengnet 2008-04-04
  • 打赏
  • 举报
回复
可以一部分一部分数据读取,减轻客户机内存的压力(如果时间上要求不是很急得话)



ydlchina 2008-03-29
  • 打赏
  • 举报
回复
这是一个非常正常的问题,李维在他的高效数据库(DBExpress)里就运行速度这个问题,提出多个解决方法,但问题似乎通过技术,就读取大量数据来说,很难做到非常完美的解决,只能就具体问题具体解决,另外他与数据集的效率也有很多关系。就我的经验而言,最好使用严格的sql语句,读取到内存的数据越少越好。
勉励前行 2008-03-28
  • 打赏
  • 举报
回复
對於ADO可能這問題比較嚴重,你可以試著用ADO原生對象的MoveNext方法,
用 ADO原生的 Recordset->Fields->Item[FieldNO]->Value 來取字段的值。

TADODataSet *DataSet ;
....
for(DataSet->Recordset->MoveFirst() ;
! DataSet->Recordset->Eof ;
DataSet->Recordset->MoveNext())
{
OleVariant V = Recordset->Fields->Item[0]->Value ; //自行處理字段值。
.....
}
//對於ADO,這樣已經算快了。但還是比DBX慢。所以建議用DBX來做。
c1aud 2008-03-28
  • 打赏
  • 举报
回复
那也不至于 越来越慢 吧。
请问还有其他的解决方法吗?
lurel 2008-03-28
  • 打赏
  • 举报
回复
因为这部分数据是放在内存中的,肯定要慢下来.
lurel 2008-03-28
  • 打赏
  • 举报
回复
数据集过大,越大越慢,建议在处理数据的时候,尽量在sql server端处理,尽量利用sql 语句和存储过程,用ADO遍历的数据尽量要少一下。如果数据过大的话会造成数据丢失。

1,178

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 数据库及相关技术
社区管理员
  • 数据库及相关技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧