我在使用Delphi TClientDataSet检索数据时遇到问题
ADO代码:
ADOQuery1.SQL.Text:='SELECT * FROM Table1 WITH (NoLock)';
DataSource1.DataSet:=ADOQuery1;
DataSource1.DataSet.Open;
DataSource1.DataSet.Last;
使用纯ADO时,上面的代码在3-6秒内返回超过180k行。
与TClientDataSet相同的代码:
ADOQuery1.SQL.Text:='SELECT * FROM Table1 WITH (NoLock)';
CDS1.SetProvider(ADOQuery1);
DataSource1.DataSet:=CDS1;
DataSource1.DataSet.Open;
DataSource1.DataSet.Last;
以下代码返回相同数量的行(超过180k)但在3-4分钟内。
CDS有什么问题?它比使用ADO慢大约100倍。 有可能解决它吗?
答案 0 :(得分:1)
使用纯ADO时,上面的代码在3-6秒内返回超过180k行。
由于某些原因,我不希望你发布的代码返回180k记录中的每一个......我希望看到在调用TADOQuery.Open之后加载的第一个“X”记录,然后是调用TADOQuery.Last时发送的最后“X”记录。去while not EoF do
代替“.Last”可能是更好的性能测试,因为(我假设)你实际上想要浏览所有记录。
在链接到DataProvider时调用TClientDataset.Last时,它很可能在您的查询中执行相当于while not EoF do
的操作,这会传输所有180k记录。此外,TClientDataset插入/追加操作往往会越慢,您拥有的记录越多。我最好的猜测是它必须时不时地重新分配它的内存缓冲区。如果是这样,我还没有找到告诉TClientDataset的方法:“嘿!支持自己,180k记录传入!”(类似于TList.SetCapacity)。
如果您有旧版本的delphi,可以帮助的一件事是Midas Speed Fix。
答案 1 :(得分:0)
在加载数据之前,尝试将CDS1.LogChanges属性设置为False。这需要在代码中完成,因为它不是已发布的属性。
从帮助文件:对于大型数据集,LogChanges的值True可能会严重影响应用程序的性能。
然后您可以在初始加载后将其打开。
答案 2 :(得分:0)
这已经很老了,但现在有很多新的Delphi程序员。这是一个独家新闻。
在delphi中使用CDS时,实际上是在创建一个内存表。你的查询可能是交换地狱。
要充分利用CDS,请使用DBX组件来获取数据。他们被称为“快进”。不使用游标在数据库中创建临时表的游标。转发只是不做ADO所做的花哨的事情。 如果您需要包含总更新通知和完全控制的海量数据集,请使用ADO。如果你需要匆忙地浏览大量数据,而CDS / DBX所在的服务器上的负载很小。
DBX的方式更难。这只是一个高速赛车。 First和Next是唯一适合他们的东西。没有更新,没有承诺,只是快速的单向关系。连接一个DBX / provider / CDS组合,你拥有它。速度和编辑能力。使用版本号检测另一个用户在编辑时对数据执行某些操作。研究提供商选项,了解如何灵活地获得权力。这几乎是Delphi中的核心。