1 [Pascal/Delphi/Sqlite3/Zeos] Kleiner Geschwindigkeitstest von Insert | Tipps zu PC und Technik

[Pascal/Delphi/Sqlite3/Zeos] Kleiner Geschwindigkeitstest von Insert

6. Mai 2018 - Lesezeit: 14 Minuten

Mich hat es interessiert, wie sich die Geschwindigkeiten von

Inserts bei SQLite3 und Zeos

verändern, mit unterschiedlichen "schreibweisen"; Und habe festgestellt, dass es durchaus erhebliche Unterschiede geben kann.

 


Ich habe den Test mehrmals durchlaufen, auch mit unterschiedlichen Zahlen und habe folgende Durchschnittszeiten bekommen:

Hier die sortierte Ergebnisse:

Benötigte Zeit % |  Funktionsname
48,57                  Test2 (Insert mit .add(Format(... siehe auch Test5 )                
17,62                  Test1 (Insert und exec... direkt hintereinander)
16,88                  Test8 (Wie Test7 + Prepare)
16,46                  Test7 (Nur ParamByName in Schleife)
0,22                   Test4 (Insert; in Transaction, außerhalb der Schleife)
0,21                   Test3 (Insert; in Transaction, innerhalb der Funktion)
0,03                   Test9 (wie 8 + Transaction)
0,01                   Test6 (Wie Test5 mit Transaction)
0,01                   Test5 (Direkt, Ohne .ParamByName.)



17,62                  Test1 (Insert und exec... direkt hintereinander)
48,57                  Test2 (Insert mit .add(Format(... siehe auch Test5 )                
0,21                   Test3 (Insert; in Transaction, innerhalb der Funktion)
0,22                   Test4 (Insert; in Transaction, außerhalb der Schleife)
0,01                   Test5 (Direkt, Ohne .ParamByName.)
0,01                   Test6 (Wie Test5 mit Transaction)
16,46                  Test7 (Nur ParamByName in Schleife)
16,88                  Test8 (Wie Test7 + Prepare)
0,03                   Test9 (wie 8 + Transaction)

 

(Funktion 2 hat im Test nicht teilgenommen. Ich war der Annahme, es ist auch mögliche mehrere Inserts mit add zu schreiben, doch das ist so nicht möglich.)

Hier die verschiedene Abschnitte:

 


function test1(testzahl: integer): string;
var
  a: integer;
begin
  for a := 1 to testzahl do
  begin
    Form1.ZQuery1.SQL.Text := 'Insert into daten2 (zahl) values (:zahl)';
    Form1.ZQuery1.ParamByName('zahl').AsInteger := a;
    Form1.ZQuery1.ExecSQL;
  end;
end;



function test2(testzahl: integer): string; //nahpets
var
  a: integer;
begin

  Form1.ZQuery1.SQL.Clear;
  for a := 1 to testzahl do
  begin
    Form1.ZQuery1.SQL.add(Format('Insert into daten2 (zahl) values (%d);', [a]));
  end;
  Form1.ZQuery1.ExecSQL;

end;


function test3(testzahl: integer): string;
var
  a: integer;
begin
  Form1.ZQuery1.SQL.Text := 'begin transaction;';
  Form1.ZQuery1.ExecSQL;

  Form1.ZQuery1.SQL.Text := '';
  for a := 1 to testzahl do
  begin
    Form1.ZQuery1.SQL.Text := 'Insert into daten2 (zahl) values (:zahl);';
    Form1.ZQuery1.ParamByName('zahl').AsInteger := a;
    Form1.ZQuery1.ExecSQL;
  end;


  Form1.ZQuery1.SQL.Text := 'Commit;';
  Form1.ZQuery1.ExecSQL;
end;




function test4(testzahl: integer): string;
var
  a: integer;
begin

  Form1.ZQuery1.SQL.Text := '';
  for a := 1 to testzahl do
  begin
    Form1.ZQuery1.SQL.Text := 'Insert into daten2 (zahl) values (:zahl);';
    Form1.ZQuery1.ParamByName('zahl').AsInteger := a;
    Form1.ZQuery1.ExecSQL;
  end;

end;



function test5(testzahl: integer): string; //mensch72
var
  a: integer;
begin

  Form1.ZQuery1.SQL.Clear;
  for a := 1 to testzahl do
  begin
    Form1.ZQuery1.SQL.Text := 'Insert into daten2 (zahl) values (' + IntToStr(a) + ')';
  end;
  Form1.ZQuery1.ExecSQL;

end;


function test6(testzahl: integer): string;
var
  a: integer;
begin
   Form1.ZQuery1.SQL.Text := 'begin transaction;';
  Form1.ZQuery1.ExecSQL;

  Form1.ZQuery1.SQL.Clear;
  for a := 1 to testzahl do
  begin
    Form1.ZQuery1.SQL.Text := 'Insert into daten2 (zahl) values (' + IntToStr(a) + ')';
  end;
  Form1.ZQuery1.ExecSQL;

  Form1.ZQuery1.SQL.Text := 'Commit;';
  Form1.ZQuery1.ExecSQL;

end;



function test7(testzahl: integer): string;
var
  a: integer;
begin
  Form1.ZQuery1.SQL.text := 'Insert into daten2 (zahl) values (:zahl);';

  for a := 1 to testzahl do begin
      Form1.ZQuery1.ParamByName('zahl').AsInteger := a;
      Form1.ZQuery1.ExecSQL;
  end;

end;

function test8(testzahl: integer): string;
var
  a: integer;
begin
  Form1.ZQuery1.SQL.text := 'Insert into daten2 (zahl) values (:zahl);';
  Form1.ZQuery1.Prepare;

  for a := 1 to testzahl do begin
      Form1.ZQuery1.ParamByName('zahl').AsInteger := a;
      Form1.ZQuery1.ExecSQL;
  end;
end;



function test9(testzahl: integer): string;
var
  a: integer;
begin
  Form1.ZQuery1.SQL.Text := 'begin transaction;';
 Form1.ZQuery1.ExecSQL;

  Form1.ZQuery1.SQL.text := 'Insert into daten2 (zahl) values (:zahl);';
  Form1.ZQuery1.Prepare;

  for a := 1 to testzahl do begin
      Form1.ZQuery1.ParamByName('zahl').AsInteger := a;
      Form1.ZQuery1.ExecSQL;
  end;

  Form1.ZQuery1.SQL.Text := 'Commit;';
 Form1.ZQuery1.ExecSQL;
 
 
 
 //Starts....

  Form1.ZQuery1.SQL.Text := 'Delete from daten2';
  Form1.ZQuery1.ExecSQL;
  test1(testzahl);

  Form1.ZQuery1.SQL.Text := 'Delete from daten2';
  Form1.ZQuery1.ExecSQL;
  test2(testzahl);

  Form1.ZQuery1.SQL.Text := 'Delete from daten2';
  Form1.ZQuery1.ExecSQL;
  test3(testzahl);



  Form1.ZQuery1.SQL.Text := 'Delete from daten2';
  Form1.ZQuery1.ExecSQL;
  Form1.ZQuery1.SQL.Text := 'begin transaction;';
  Form1.ZQuery1.ExecSQL;
  test4(testzahl);
  Form1.ZQuery1.SQL.Text := 'Commit;';
  Form1.ZQuery1.ExecSQL;


  Form1.ZQuery1.SQL.Text := 'Delete from daten2';
  Form1.ZQuery1.ExecSQL;
  test5(testzahl);


  Form1.ZQuery1.SQL.Text := 'Delete from daten2';
  Form1.ZQuery1.ExecSQL;
  test6(testzahl);


  Form1.ZQuery1.SQL.Text := 'Delete from daten2';
  Form1.ZQuery1.ExecSQL;
  test7(testzahl);


  Form1.ZQuery1.SQL.Text := 'Delete from daten2';
  Form1.ZQuery1.ExecSQL;
  test8(testzahl);


  Form1.ZQuery1.SQL.Text := 'Delete from daten2';
  Form1.ZQuery1.ExecSQL;
  test9(testzahl);

 

Test2,1,8,7: Sind deutlich langsam. Sollte man so keinesfalls verwenden, wenn Geschwindigkeit ein Kriterium sein soll.
Nur ParamByName in der schleife (Test7) ergibt für sich keinen Geschwindigkeitsvorteil, auch nicht mit Prepare verbunden (Test8); Und ergibt nur Sinn, wenn man diese mit Transaction verbindet (Test9). Mit Format() (Test2) sollte man bzgl. Schnelligkeit eher vorsichtig sein, diese war sogar fast dreimal solangsam wie Test1 (Insert,Exec direkt hintereinander).


Test3,4: Insert mit Transactionen gehen bereits erheblich schneller und können/sollten verwendet werden. Dabei spielt es keine Rolle ob "begin transaction / commit) innerhalb der Funktion oder außerhalb ist.

Test9,6,5: Sind nochmal um ca. 0,2 % schneller als Test3 und 4. Variablen direkt in die SQL Anweisung zu schreiben (Test5), war das schnellste; Gleiches mit Transaction (Test6) ist sogar einen Tick langsamer und wird nicht wirklich benötigt.

 

 

 











Es wurden noch keine Kommentare verfasst, sei der erste!