【发布时间】:2016-08-14 18:42:54
【问题描述】:
我在一个应用程序中使用 TClientDataSet 来管理从多个 CSV 文件导入的大量数据。这总共可以是一百万个或更多条目。我希望能够删除与特定 CSV 文件关联的所有数据集条目,但删除大量项目的时间非常慢。
为了测试我是否在做一些愚蠢的事情,我创建了一个简单的控制台应用程序。它所做的只是:
-
创建一个定义了 1 个字段 (ID) 的 TClientDataSet 实例:
CDS := TClientDataSet.Create(nil); CDS.FieldDefs.Add('ID', ftInteger); CDS.CreateDataSet; CDS.LogChanges := False; -
追加 100,000 个项目(需要 0.1 秒):
for i := 1 to 100000 do begin CDS.AppendRecord([i]); end; -
删除 50,000 个项目(大约需要 4 秒,或使用
LogChanges=TRUE大约需要 4.4 秒):CDS.First; while CDS['ID'] <= 50000 do CDS.Delete;
如果我的数据集中有 150 万个项目,并且想要删除 0.50 万个条目,那么通过这种方法删除项目需要很长时间,我什至无法测量它。
作为目前的解决方法,我必须创建一个新数据集,然后将我想要保留的所有项目复制到新副本并删除原始副本。除非我只从原始数据集中删除一小部分条目,否则此方法要快得多。
也许我没有使用最合适的方法来尝试从数据集中删除项目?我猜我删除的每个项目都会触发一堆内部处理。有什么方法可以一次删除我丢失的一系列项目吗?或许我可以根据该索引设置一个索引和一个范围,然后一次操作删除当前范围内的所有项目?
也许问题出在 ClientDataSet 而不是我?也许我需要使用不同的组件。有什么建议吗?
【问题讨论】:
-
可能你忘了关掉
LogChanges。 -
有趣,应该有区别,因为维护增量并不便宜。
-
正如您提到的聚合和索引,这些可能是罪魁祸首;尝试在批量删除操作之前禁用它们并在之后重新启用它们(如果需要)。 (问题可能是它们在每次删除后都会更新,这是完全没有必要的。)
-
我认为这是意料之中的。删除需要移动文件中的数据。
-
Delphi 的哪个版本?你试过 Andreas Hausladen 的 MidasSpeedFix 吗?
标签: delphi tclientdataset