在我正在建设的应用程序中,我有一个大型数据库,其中有一个表格" People"拥有100,000 +行。此外,该表中的条目包含两种类型的数据: 父类型和子类型,其中每个子类型条目在特殊的" Child_OF"中具有其父类的数据库ID。柱。
在内存中,两个数据库条目类型都由相应的类表示" 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 ...是否有更快的返工?基本上可以假设我的数据集是静态的(在创建父项列表期间)和网络延迟无限:)(也就是说,我首先想要从内存中执行子项到父项的分配)。 非常感谢!
btw我正在使用Microsoft SQL Server 2012.
答案 0 :(得分:6)
如果您不想更改代码/逻辑,可以在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
这将为该字段创建索引。它需要花费少量时间来过滤没有索引的大量时间。