TClientDataSet使用100K +行非常慢

时间:2015-01-15 09:22:20

标签: performance delphi tclientdataset

我在使用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倍。 有可能解决它吗?

3 个答案:

答案 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中的核心。