Delphi以多列数据集的速度呈指数级增长

时间:2015-12-02 17:44:48

标签: database performance delphi

我想知道是否有人遇到过这个最近让我烦恼的问题。 假设我有一个100+列表。当我需要从中选择一条记录时需要花费大量时间。 查看调试器,我可以将其缩小到绑定db.pas中的字段。 显然,对于每个字段,它都会杀死并重建内部字段定义列表。 我通常通过保持数据集处于活动状态并使用新的关键字段值刷新它来解决此问题。遗憾的是,它不适用于aducom sqlite组件。

enter image description here

重现的步骤:

代码:

procedure TForm6.Timer1Timer(Sender: TObject);
var
  s: string;
  i, n, j: Integer;
  tick: DWORD;
begin
  for j := 0 to 10 do begin
    N := 1 shl j;
    Memo1.Lines.Add('Columns count: ' + IntToStr(N));

    ASQLite3Query1.SQL.Text := 'drop table if exists test';
    ASQLite3Query1.ExecSQL;
    s := '';
    for i := 1 to N do
      s := s + 'field' + IntToStr(i) + ' integer' + IfThen(i<n, ',');
    ASQLite3Query1.SQL.Text := 'create table test(' + s + ');';
    ASQLite3Query1.ExecSQL;

    ASQLite3Query1.SQL.Text := 'select * from test';
    tick := GetTickCount;
    ASQLite3Query1.Open;
    ASQLite3Query1.Close;
    Memo1.Lines.Add('Time elapsed, ms: ' + IntToStr(GetTickCount - tick));
  end;
  Timer1.Enabled := false;
end;

输出:

Columns count: 1
Time elapsed, ms: 0
Columns count: 2
Time elapsed, ms: 0
Columns count: 4
Time elapsed, ms: 0
Columns count: 8
Time elapsed, ms: 0
Columns count: 16
Time elapsed, ms: 0
Columns count: 32
Time elapsed, ms: 0
Columns count: 64
Time elapsed, ms: 31
Columns count: 128
Time elapsed, ms: 94
Columns count: 256
Time elapsed, ms: 203
Columns count: 512
Time elapsed, ms: 671
Columns count: 1024
Time elapsed, ms: 4976
编辑:我错误地使用了“指数”这个词。字段计数和时间之间的函数似乎是二次的(给出或取相当于FieldDefs和CPU缓存的大小)。

1 个答案:

答案 0 :(得分:0)

我没有Aducom组件,所以我无法给你一个&#34;如何引导&#34;我可以测试,但我已经使用TClientDataSet设置了测试平台,并建议如下。我假设您的TAsqlite3Query没有任何计算,查找或聚合字段(但如果它也适用于它们)。

  • 在DB.TDataSet.BindFields上放置一个断点,编译并运行。

  • 当断点触发时,单步执行BindFields,并追踪它调用的所有内容。

  • 在跟踪来自BindFields的调用时,请注意数据集是否具有持久性TField 持久性TFieldDefs的影响。所有TDataSet后代都实现了持久性TFields,但并非所有实现持久性TFieldDefs,并且我不知道Aducom是否会这样做。

分析这些步骤,应该让您更清楚地了解持久性TField和持久性TFieldDefs(如果可用)对DoBindFields的执行速度有何影响,并且可能有助于您对可能的pinchpoints进行归零,如果它还没有清楚你的代码是否会受益于持久性TFields和/或持久性TFieldDefs。