Entwickler-Ecke

Datenbanken - Testdaten schnell erstellen


trm - Di 27.11.12 22:52
Titel: Testdaten schnell erstellen
Huhu,

ich bin gerade dabei einige Programme auf eine neue Datenbank umzustellen.

In diesem Zuge erzeuge ich immer mal Testdatensätze.

Im Moment passiert das per Schleife.

Gibt es ein SQL Verfahren, mit dem ich schnell Daten in eine Datenbank schreiben kann als meine aktuelle Methode?


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
procedure TForm1.Panel7Click(Sender: TObject);
var
  X: Integer;
  dummyStrings: TStrings;
  str1, str2: string;
begin

  dummyStrings := TStringList.Create;
  dummyStrings.Clear;

  for X := 0 to 1000000 do
  begin
    str1 := Random_String(100);
    str2 := Random_String(100);


// Hier hätte ich gern einfach eine Möglichkeit, dass die Daten schneller geschrieben werden statt über ein Array (StringList)
    dummyStrings.Add('insert into bibo (name,autor) values (''' + str1 + ''', ''' + str1 + ''');');

  end;
  CreateDBsql(ABSTable1, ABSQuery1, dummyStrings);
  dummyStrings.Free;

end;


function CreateDBsql(Table: TABSTable; Query: TABSQuery; SQLstrings: TStrings): Integer;
begin

  Table.Close; //nur für den Fall, dass die noch offen ist, sonst ohne Bedeutung hier
  Query.SQL.Text := SQLstrings.Text;
  Query.ExecSQL;

end;


Xion - Mi 28.11.12 09:19

In SQLite würde man so vorgehen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
DB.BeginTransaction;
for X := 0 to 1000000 do
  begin
    str1 := Random_String(100);
    str2 := Random_String(100);
    DB.ExecSQL('insert into bibo (name,autor) values (''' + str1 + ''', ''' + str1 + ''');');
  end;
DB.Commit;


Alle inserts werden dann in einer Transaktion durchgeführt. Dies ist erheblich schneller als jedes Insert einzeln durchzuführen. Außerdem sollte auf diese Weise bereits während dem Durchlauf der Schleife, das Insert in der DB durchgeführt werden.

Wie es genau bei dir abläuft weiß ich nicht, da ich nicht beurteilen kann, was die Komponente mit dem langen String macht. Ich habe mal in die Doku geschaut, und ich bilde mir ein, dein Verfahren ist richtig so, denn spezielle Transaction-Befehle scheint es nicht zu geben.
[PS: http://www.componentace.com/help/absdb_manual/faq.htm erster Punkt. StartTransaction ist eine Methode von TABSDatabase. http://www.componentace.com/help/absdb_manual/tabsdatabase_methods.htm ]

Vielleicht hilft dir aber das hier zumindest ein bisschen:
http://www.componentace.com/help/absdb_manual/improvingoverallperformance.htm


trm - Mi 28.11.12 10:41

Danke Xion, jedoch ist das im Prinzip ein ähnliches Vorgehen, welches ich im Moment nutze.

Ich hoffte, dass es ein SQL Verfahren gibt, welches ähnlich einer Multiplikation arbeitet.

Auf die Random-Werte könnte ich auch Verzichten. Mir geht es im Moment nur um die Menge an Daten.

Die Schleife, welche die Stringlist füllt ist die Bremse.


Martok - Mi 28.11.12 16:30

Hi!

Du willst Prepared Statements mit Parametern. Mal von den offensichtlichen Sicherheitsaspekten abgesehen, bringt dir das auch noch Geschwindigkeit, da das SQL nur einmal geparst wird und dann nur noch mit der Information "und jetzt führe das bitte mit diesen Daten aus" aufgerufen wird.

Grüße,
Martok


Sinspin - Mi 28.11.12 17:28

Es geht hier ja nicht um Sicherheit, sondern um Speed. Eine Möglicheit eine Stringliste schneller zu bekommen ist Capacity. Einfach auf die Anzahl der zu erwartenten Strings setzen und es wird schneller. Die Variante von Xion sogt dafür das die DB selber das einfügen noch weiter optimieren kann. Aber das macht eigentlich nur Sinn bei einem Server wenn man mehr als eine Connection die DB mit Daten beschießt.
Ich Denke das es via Prepared Statements am schnellsten geht. Transactionhandling hat im realen Anwendungsfall aber als weiteres des Vorteil das man keinen Schrott in die DB schreibt falls aus irgend einem Grund mal was nicht klappt.


trm - Mi 28.11.12 19:36

Danke für eure Antworten :)