2016-04-28 16 views
0

私のコードをより効果的にするための助言や助けを求めています。私はたくさんのテーブルとデータで作業しています(約100万レコード) これで簡単な投稿でFiredacクエリを使用します。私のコードは正常に動作しますが、実行は最初から長くかかります。 (2時間以上) フィールドごとにパラメータを更新する必要があります。データベースはfirebird 2.5です。私のコードはSQLステートメントの収集

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; 

...のように見えます。しかし、これは非常に遅いです...

私がいない1、すべてのテーブルのSQL-Sでブロックを作り、一緒に挿入したいと思います私の他のコードは次のようになります1

..

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を収集した後に実行したい

誰かが私にこのより良い解決法やアドバイスを与えることができますか?答えをありがとう!

あなたループクエリのすべての行を超えると、すべてのフィールドを超えることあなたループ内:

+0

インデックスを持たない一時テーブルに値を挿入します。完了したら、一時テーブルから実際のテーブルに 'insert select'を実行してください:http://stackoverflow.com/questions/21115720/insert-select-in-firebird – Johan

+0

トランザクションを使用していますか?すなわち、「FDConnection1.StartTransaction」および「FDConnection1.Commit」。 –

+0

ええ、テーブルポストの後にコミットしてください。 – Steve88

答えて

1

あなたのループが丸い間違った方法です。
しかし、クエリ内のフィールドメタデータはすべての行で同じです。
はそうのように離れて二つのループを引い:

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; 

行のメタデータの収集とあなたは非常に多くのものをスピードアップする必要があり、ループのうち、更新の投稿を引っ張って。さらに

ない

  • 十分高速カスタムアレイの行のデータを収集する(上記参照)。
  • このデータを使用して、インデックスのない一時テーブルを作成します。
  • テンポラリテーブルにデータを挿入します。
  • 実テーブルのインデックスを無効にします。
  • 一時テーブルから実テーブルへのselect-insert(select-update)を実行します。
  • 実テーブルでインデックスを有効にします。
  • 一時テーブルを削除します。