2016-04-28 5 views
0

Ich möchte um Rat und Hilfe bitten, um meinen Code effektiver zu machen. Ich arbeite mit vielen Tabellen und Daten (ungefähr 1 Million Aufzeichnung) Jetzt benutze ich eine Firedac Abfrage mit seinem einfachen Pfosten. Mein Code funktioniert gut, aber das Laufen dauert von Anfang an lange. (mehr als zwei Stunden) Ich muss die Parameter Feld für Feld aktualisieren. Datenbank ist Firebird 2.5.Sammeln von SQL-Anweisungen

Mein Code sieht aus wie ...

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; 

Aber das ist sehr langsam ...

Ich möchte einen Block mit allen in der Tabelle SQL-s machen und gemeinsam einsetzen, nicht ein von einem

Meine anderen Code wie folgt aussieht ..

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; 

Variablen sind Varianten. Nachdem ich alle SQL-s gesammelt habe möchte ich sie ausführen

Kann mir jemand eine bessere Lösung oder einen besseren Rat geben? Danke für die Antworten!

+0

Fügen Sie die Werte in eine temporäre Tabelle ohne Indizes ein. Wenn du fertig bist, führe einen 'insert select' aus der temporären Tabelle in deine reale Tabelle aus: http://stackoverflow.com/questions/21115720/insert-select-in-firebird – Johan

+0

Benutzt du eine Transaktion? d.h. 'FDConnection1.StartTransaction' und' FDConnection1.Commit'. –

+0

yeah, Commit nach den Tabellen posten. – Steve88

Antwort

1

Ihre Schleife ist falsch herum:

Sie Schleife über jede Zeile der Abfrage und im Inneren, dass Sie eine Schleife über jedes Feld.
Die Feldmetadaten in einer Abfrage bleiben jedoch für jede Zeile gleich.
Ziehen Sie die beiden Schleifen auseinander wie so:

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; 

die Sammlung für Zeilen Metadaten und die Entsendung von Updates aus der Schleife Durch Ziehen Sie die Dinge ziemlich viel beschleunigen sollten.

Immer noch nicht schnell genug

  • Sammeln die Zeilendaten in einem benutzerdefinierten Feld (siehe oben).
  • Verwenden Sie diese Daten, um eine temporäre Tabelle ohne Indizes zu erstellen.
  • Daten in die temporäre Tabelle einfügen.
  • Disable Indizierung auf den realen Tisch (en).
  • Führen Sie eine Select-Einfügung (Select-Update) aus der temporären Tabelle in die reale Tabelle durch.
  • Aktivieren Sie die Indizierung für die realen Tabelle (n).
  • Löschen Sie die Tempentabelle.