【问题标题】:Collecting SQL statements收集 SQL 语句
【发布时间】:2016-04-28 17:53:16
【问题描述】:

我想寻求建议和帮助,以使我的代码更有效。我正在处理大量表格和数据(大约 100 万条记录) 现在我使用 Firedac Query 和它的简单帖子。我的代码运行良好,但从一开始就运行很长时间。 (两个多小时) 我必须逐个字段更新参数。数据库是 firebird 2.5。

我的代码看起来像...

while not qry_sample eof do
begin
  qry_sample.edit;

  for C := 0 to qry_sample.fields.count -1 do
  begin 
   //Here I do the parameter changes for every qry_sample.fields[C].value
   //for example I add new value for all the primary keys and foreign keys 
   //I got the new ID-s from dictionaries
  end;
  qry_sample.post;
end;    
qry_sample.next;

但这很慢......

我想把所有的表SQL-s做成一个block一起插入,不是一个一个

我的其他代码看起来像..

for C := 0 to qry_SQL.Fields.Count -1 do
begin
  if not vFields.IsEmpty then
    vFields := vFields + ',';

  vFields := vFields + qry_SQL.Fields[C].FieldName;

end;

while not qry_SQL.Eof do
begin
  vValues := '';
  SQL := '';

  for C := 0 to qry_SQL.Fields.Count -1 do
  begin
    vValues := vValues + ',';
    vValues := vValues + chr(39)+ vartostr(qry_SQL.Fields[C].Value) +chr(39);
  end;
  qry_SQL.Next;

  SQL := SQL + #13#10 + 'insert into ' + vSourceTableName + '(' + vFields + ') ' +
  'values ('+ vValues + ');';
end;

变量是变体。在我收集了所有想要执行的 SQL 之后

有人可以为此提供更好的解决方案或建议吗?感谢您的回答!

【问题讨论】:

  • 将值插入到没有索引的临时表中。完成后,将临时表中的insert select 插入到真实表中,请参阅:stackoverflow.com/questions/21115720/insert-select-in-firebird
  • 你在使用事务吗?即FDConnection1.StartTransactionFDConnection1.Commit
  • 是的,在表格发布后提交。

标签: sql delphi firebird


【解决方案1】:

你的循环是错误的:

while not qry_sample eof do
begin
  qry_sample.edit;

  for C := 0 to qry_sample.fields.count -1 do
  begin 
  end;
  qry_sample.post;
end;    
qry_sample.next;

您遍历查询的每一行,并在其中遍历每个字段。
但是查询中的字段元数据在每一行都保持不变。
像这样拉开两个循环:

type
  TFieldData = record
    //Whatever data you want to collect about the fields
  end;

var
  Fields: array of TFieldData;
begin
  SetLength(Fields, qry_sample.Field.Count);
  for c:= 0 to qry_sample.Fields.Count -1 do begin
    //Store the relevant data in the fields array
    Fields[c].Fieldname:= qry_sample.Fields[i].Fieldname;
  end; {for fields}
  while not(qry_sample.eof) do begin
    //Do stuff
  end; {while}
  qry_sample.post;

通过提取行元数据的集合并将更新发布到循环之外,您应该可以大大加快速度。

还是不够快

  • 在自定义数组中收集行数据(见上文)。
  • 使用这些数据创建一个没有索引的临时表。
  • 将数据插入临时 桌子。
  • 在真实表上禁用索引。
  • 从临时表到实际表执行选择插入(选择更新)。
  • 在真实表上启用索引。
  • 删除临时表。

【讨论】:

    猜你喜欢
    • 2012-01-09
    • 2013-11-17
    • 1970-01-01
    • 1970-01-01
    • 2012-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多