优化循环数据集

时间:2013-05-08 08:36:32

标签: delphi loops

我有一些像这样的代码

dxMemOrdered : TdxMemData;
while not qrySandbox2.EOF do
    begin
      dxMemOrdered.append;
      dxMemOrderedTotal.asCurrency := qrySandbox2.FieldByName('TOTAL').asCurrency;
      dxMemOrdered.post;
      qrySandbox2.Next;
    end;

此代码在线程中执行。当有大量记录说“400000”时,需要大约25分钟来解析它。有什么办法可以通过优化循环来减小尺寸吗?任何帮助将不胜感激。

更新

根据建议,我做了以下更改

dxMemOrdered : TdxMemData;
qrySandbox2.DisableControls;
while not qrySandbox2.Recordset.EOF do
    begin
      dxMemOrdered.append;
      dxMemOrderedTotal.asCurrency := Recordset.Fields['TOTAL'].Value;  
      dxMemOrdered.post;
      qrySandbox2.Next;
    end;
qrySandbox2.EnableControls;

我的输出时间从15分钟提高到2分钟。谢谢你们

4 个答案:

答案 0 :(得分:2)

按性能提升的顺序与您的工作有关的一些想法:

1)检查您使用的SQL方言是否允许您使用直接从/ INSERT中选择的查询。这取决于您正在使用的数据库。

2)确保如果你的数据集没有耦合到可视控件,你可以在这个循环中调用DisableControls / EnableControls

3)此代码是否必须在主程序线程中运行?也许您可以在用户/程序继续执行其他操作时将其发送到单独的线程

4)当您必须处理非常大的数据时,批量插入是可行的方法。许多数据库都有批量插入文本文件数据的选项。首先写入文本文件然后批量插入比单个插入更快。同样,这取决于您的数据库类型。

[编辑:我只是看到你插入了它是TdxMemData的信息,因此其中一些不再适用。你已经穿线了,错过了;-)。我将这些建议留给了其他有类似问题的读者]

答案 1 :(得分:2)

没有看到更多代码,我可以做的唯一建议是确保禁用任何使用内存表的可视控件。假设您有一个名为Grid的cxgrid链接到您的dxMemOrdered内存表:

var    
  dxMemOrdered: TdxMemData;
...

Grid.BeginUpdate;
try
  while not qrySandbox2.EOF do
  begin
    dxMemOrdered.append;
    dxMemOrderedTotal.asCurrency := qrySandbox2.FieldByName('TOTAL').asCurrency;
    dxMemOrdered.Post;
    qrySandbox2.Next;
  end;
finally
  Grid.EndUpdate;
end;

答案 2 :(得分:0)

让SQL完成工作而不是通过Delphi中的循环迭代会好得多。尝试查询,例如

insert into dxMemOrdered (total)
select total from qrySandbox2

'total'是dxMemOrdered中唯一的字段吗?我希望它不是主键,否则你可能会发生冲突,这意味着不会添加行。

答案 3 :(得分:0)

实际上你可以做很多事情来加速你的线程。

首先是从更广泛的角度来看问题:

  • 我是从缓存/快速磁盘中获取数据,可能是在内存中移动了吗?

  • 在手动汇总总数时,我做的是正确的吗? SQL引擎特别针对这些事情进行了优化,您需要做的就是定义一个额外的逻辑字段来存储SQL聚合结果。

可能会对大量循环进行改进的另一个小优化是不使用如下构造:

  • Recordset.Fields [ 'TOTAL']。值

  • Recordset.FieldByName( '总计')。值

但要使用字段编辑器添加字段,然后直接访问右侧字段。您将在字段集合中保存整个循环,否则将在每个字段上,在每个下一条记录上执行。