我有一些像这样的代码
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分钟。谢谢你们
答案 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( '总计')。值
但要使用字段编辑器添加字段,然后直接访问右侧字段。您将在字段集合中保存整个循环,否则将在每个字段上,在每个下一条记录上执行。