2

我有一个类似这样的代码

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

4 回答 4

3

在没有看到更多代码的情况下,我能提出的唯一建议是确保禁用任何使用内存表的视觉控件。假设您有一个名为 cxgridGrid的链接到您的 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;
于 2013-05-08T09:48:35.650 回答
2

一些关于性能增益与您要做的工作的想法:

1) 检查您使用的 SQL 方言是否允许您使用直接从/插入到的查询。这取决于您使用的数据库。

2) 确保如果您的数据集未与可视控件耦合,则围绕此循环调用 DisableControls/EnableControls

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

4)当你必须处理非常大的数据时,批量插入是要走的路。许多数据库都有从文本文件批量插入数据的选项。首先写入文本文件然后批量插入比单独插入要快得多。同样,这取决于您的数据库类型。

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

于 2013-05-08T08:48:44.483 回答
0

让 SQL 完成工作比在 Delphi 中通过循环进行迭代要好得多。尝试查询,例如

insert into dxMemOrdered (total)
select total from qrySandbox2

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

于 2013-05-08T12:44:52.890 回答
0

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

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

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

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

另一个可能对大量循环带来改进的小优化是不使用以下结构:

  • Recordset.Fields['TOTAL'].Value

  • Recordset.FieldByName('TOTAL').Value

但是要使用字段编辑器添加字段,然后直接访问正确的字段。您将通过 fields 集合保存整个循环,否则将在每个字段、每个下一条记录上执行。

于 2013-12-19T10:07:26.853 回答