Delphi + Firebird 1.5: Geschwindigkeit

14/05/2008 - 15:01 von Jens Tönsing | Report spam
Hallo,

ich bin dabei, mich langsam in die Tiefen von Delphi und Firebird (1.5)
einzuarbeiten.
Ich frage mich, welche Möglichkeit die Beste ist, wenn man viele
Datensàtze in eine Tabelle einfügen möchte (z.B. wenn man Daten
importiert).

Möglichkeit 1:
Man bastelt für jeden Datensatz ein SQL-Statement:

q := TSQLQuery.Create(self);
q.SqlConnection := ...

for i := 1 to x
begin
q.sql.clear;
q.sql.add ('insert into tabelle (ID, Name)');
q.sql.add ('VALUES(' + intToStr(i) + ', Name..'));
q.ExcecSql;
end;
q.Free;

Möglichkeit 2:
Quasi identisch mit Möglichkeit 1, nur dass man sich den SQL-String
vorher zusammenbastelt und in einem Rutsch an q übergibt:

q := TSQLQuery.Create(self);
q.SqlConnection := ...

for i := 1 to x
begin
s := 'insert into tabelle (ID, Name)' +
'VALUES(' + intToStr(i) + ', Name..');
q.sql.clear;
q.sql.add (s);
q.ExcecSql;
end;
q.Free;

Hat man hier eine Vorteil, weil man q.sql.add nur einmal aufruft? Mein
Beispiel ist ja sehr klein, es könnte gut sein, dass man 20x q.sql.add
aufruft, um das Statement zusammenzusetzen. Hat das spürbare
Auswirkungen?

Möglichkeit 3:
Sql-parameter

q := TSQLQuery.Create(self);
q.SqlConnection := ...
q.sql.clear;
q.sql.add ('insert into tabelle (ID, Name)');
q.sql.add ('VALUES(:ID,:Name)');
q.PrepareStatement;

for i := 1 to x
begin
q.paramByName('ID').AsInteger := i;
q.paramByName('Name').AsString := 'Name...';
q.Prepared := True
q.ExcecSql;
end;
q.Free;

Möglichkeit 4:
???????

Welche Art verwendet Ihr und warum? Mir geht es dabei halt um den Fall,
dass man sehr viele Datensàtze mit Insert einfügt. Wenn nur einen
Datensatz in eine Tabelle einfügt, ist klar, dass man subjektiv keinen
Unterschied merken wird. Aber wenn man 50.000 Datensàtze einliest, macht
es in Summe bestimmt einen Unterschied, oder?

Gruß,
Jens

Spritkostentabelle und Erfahrungsdatenbank für Gasfahrer:
http://www.jens-toensing.de
Wenn die Bàuerin Striptease tanzt, sich das Vieh im Stall verschanzt!
 

Lesen sie die antworten

#1 lothar.armbruester
14/05/2008 - 17:47 | Warnen spam
Jens Tönsing writes:

Hallo,

ich bin dabei, mich langsam in die Tiefen von Delphi und Firebird (1.5)
einzuarbeiten.
Ich frage mich, welche Möglichkeit die Beste ist, wenn man viele
Datensàtze in eine Tabelle einfügen möchte (z.B. wenn man Daten
importiert).

Möglichkeit 1:
Man bastelt für jeden Datensatz ein SQL-Statement:

q := TSQLQuery.Create(self);
q.SqlConnection := ...

for i := 1 to x
begin
q.sql.clear;
q.sql.add ('insert into tabelle (ID, Name)');
q.sql.add ('VALUES(' + intToStr(i) + ', Name..'));
q.ExcecSql;
end;
q.Free;



Das ist anfàllig für SQL-Injection und Pathologische Namen.
Ist Name z.B. D'Artagnan, zerbröselt Dir das Deinen SQL.

Möglichkeit 2:
Quasi identisch mit Möglichkeit 1, nur dass man sich den SQL-String
vorher zusammenbastelt und in einem Rutsch an q übergibt:

q := TSQLQuery.Create(self);
q.SqlConnection := ...

for i := 1 to x
begin
s := 'insert into tabelle (ID, Name)' +
'VALUES(' + intToStr(i) + ', Name..');
q.sql.clear;
q.sql.add (s);
q.ExcecSql;
end;
q.Free;

Hat man hier eine Vorteil, weil man q.sql.add nur einmal aufruft? Mein
Beispiel ist ja sehr klein, es könnte gut sein, dass man 20x q.sql.add
aufruft, um das Statement zusammenzusetzen. Hat das spürbare
Auswirkungen?



Der Client ist in der Regel nie das bremsende Element. Ich denke, das SQL.Add
ist zwar aufwàndiger als die Stringverkettung, aber solange Du weniger als
einige Millionen Datensàtze verarbeitest sollte der Effekt gereade messbar
sein.

Möglichkeit 3:
Sql-parameter

q := TSQLQuery.Create(self);
q.SqlConnection := ...
q.sql.clear;
q.sql.add ('insert into tabelle (ID, Name)');
q.sql.add ('VALUES(:ID,:Name)');
q.PrepareStatement;

for i := 1 to x
begin
q.paramByName('ID').AsInteger := i;
q.paramByName('Name').AsString := 'Name...';
q.Prepared := True
q.ExcecSql;
end;
q.Free;



Das ist z.B. für Oracle die schnellste Lösung, wenn man mal von
SQL*Loader etc. absieht. Für FB sollte das àhnlich sein.
Zum einen wird der SQL nur einmal geparst und Du schickst nur
noch Daten über das Netz und nicht mehr den SQL.
Außerdem können Namen mit für SQL reservierten Zeichen nicht mehr
das ganze zerbröseln.

[...]

Und tschüss,
Lothar

Lothar Armbrüster |
Hauptstr. 26 |
65346 Eltville |

Ähnliche fragen