【问题标题】:Delphi ADO dataset FilterDelphi ADO 数据集过滤器
【发布时间】:2014-03-26 15:11:45
【问题描述】:

在我在工作中构建的一个应用程序中,我有一个大型数据库,其中有一个表说“人”,有 100,000 多行。此外,此表中的条目包含两种类型的数据: 父类型和子类型,其中每个子类型条目在特殊的“Child_OF”列中具有其父级的数据库 ID。

在内存中,两种 db 条目类型都由相应的类“TParent”和“TChild”表示,其中每个父类都有字段“children : TList”。

使用 ADO 最快的方法是: - 创建父母列表并正确分配他们的孩子...

在我看来……可以通过以下方式解决问题 1)批量(通过一个sql查询)从表中检索所有父母并创建带有空子列表的父母列表。 2)批量检索所有孩子,并为每个父母尝试从相应的数据集中找到他/她的孩子。

这是我对程序分配阶段的想法的一个例子......

procedure assignParentsTheirChildren(parentList: TList<TParent>;
  ma_people: TADOTable);
var
  i: Integer;
  qry: TADOQuery;
  aChild: TChild;
  aParent: TParent;
begin

  // create the query
  qry := TADOQuery.Create(nil);
  qry.Connection := ma_people.Connection;
  // set the sql statement to fetch all children ...
  qry.SQL.Clear;
  qry.SQL.Add('Select * from ' + ma_people.TableName + ' WHERE ChildOF <> ' +
    QuotedStr(''));
  // supposedly do some optimization---
  qry.CursorLocation := clUseClient; // load whole recordset in memory
  qry.DisableControls;
  // disable controls ensures that no dataset bound control will be updated while iterating the recordset
  qry.CursorType := ctStatic; // set cursor to static
  // open dataset
  qry.Open;
  // ***EDIT*** for completeness I add the suggestion made by Agustin Seifert below
  qry.RecordSet.Fields['ChildOf'].Properties.Item['Optimize'].value := true;

  for i := 0 to parentList.count - 1 do
  begin
    // get daddy
    aParent := parentList[i];

    qry.Filter := 'ChildOF = ' + QuotedStr(IntToStr(aParent.parentID));
    qry.Filtered := true;

    while (not qry.EOF) do
    begin
      aChild := TChild.Create;
      getChildFromQuery(aChild, qry); // fills in the fields of TChild class...
      aParent.children.Add(aChild);
      qry.Next;
    end;

  end;
  qry.Free;
end;

我猜上述代码的最大瓶颈是我正在为每个新父母过滤数据。使用 seek() 或 locate/find... 是否有更快的返工?基本上可以假设我的数据集是静态的(在创建父母列表期间)并且网络延迟无限:)(也就是说,我首先想从内存中将孩子分配给父母)。 非常感谢!

顺便说一句,我使用的是 Microsoft SQL Server 2012。

【问题讨论】:

  • 你真的需要一次将所有的父母和孩子都加载到内存中吗?您可以实现延迟加载机制,只需使用最少的信息填充父列表,然后在需要时加载扩展的详细信息(如子信息)。
  • @Andy_D 是的.. 不幸的是,我需要同时为所有的父母和孩子工作。

标签: performance delphi ado


【解决方案1】:

如果您不想更改代码/逻辑,有一种方法可以优化 ADO 中的筛选、查找、排序操作。 访问记录集并优化相关字段:

var
  qry: TADOQuery;
  rs: _Recordset;
  ...
begin
  ...
  //after qry.Open;
  rs := qry.Recordset;
  rs.Fields['YourField'].Properties.Item['Optimize'].Value := True; //YourField = ChildOF in your case

这将为该字段创建一个索引。与在没有索引的情况下过滤很多次所需的时间相比,它需要的时间很短。

msdn: Optimize Property-Dynamic (ADO)

【讨论】:

  • 谢谢!这个小的优化过程给了我 10 倍或更多的加速!我绝对推荐它。让我们看看是否还有其他建议。
  • 是的!太好了,你的逻辑还是一样的,你不需要再测试了。它是透明的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多