Delphi-PRAXiS
Seite 1 von 3  1 23   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   SQL "Update or Insert" langsam (https://www.delphipraxis.net/191313-sql-update-insert-langsam.html)

BlueStarHH 2. Jan 2017 13:06

Datenbank: Firebird • Version: 2.5 • Zugriff über: IBDAC

SQL "Update or Insert" langsam
 
Hallo,

ich führe ca. 2000 "Update or Insert"-Statements mit einem TIBCQuery aus. Das dauert ca. 2,5 Sekunden und ist zu langsam. Ist das normal, dass das so lange dauert oder kann man das beschleuningen? (Zum Vergleich: Wenn ich die selben Daten ohne Datenbank in eine Ini-Datei schreibe ist das in 0,5 Sekunden erledigt.)

Code:
Transaction.StartTransaction;

for i := 0 to 2000 do
begin
  Query.SQL.Text := 'Update or insert into foo (A, B, C) values (:a, :b, :c)';
  Query.ParamByName('a').AsString := 'v1';
  Query.ParamByName('b').AsString := 'v2';
  Query.ParamByName('c').AsString := 'v3';
  Query.Execute;
end;

Transaction.Commit;

DeddyH 2. Jan 2017 13:12

AW: SQL "Update or Insert" langsam
 
Wieso setzt Du innerhalb der Schleife jedesmal die SQL-Eigenschaft neu? Und fehlt da nicht ein MATCHING in Deinem Statement?

SProske 2. Jan 2017 13:17

AW: SQL "Update or Insert" langsam
 
Zitat:

Zitat von DeddyH (Beitrag 1357737)
Und fehlt da nicht ein MATCHING in Deinem Statement?

Nicht zwangsläufig: In the absence of a MATCHING clause, matching is done against the primary key.

Siehe https://firebirdsql.org/refdocs/lang...or-insert.html

BlueStarHH 2. Jan 2017 13:25

AW: SQL "Update or Insert" langsam
 
Zitat:

Zitat von DeddyH (Beitrag 1357737)
Wieso setzt Du innerhalb der Schleife jedesmal die SQL-Eigenschaft neu? Und fehlt da nicht ein MATCHING in Deinem Statement?

Pseudocode ;-) Die Schleife und der Inhalt sind im echten Code ganz weit von einander weg und entkoppelt, dass es nur so geht. Ich kann nur den Inhalt in der Schleife kontrollieren. Ob da nun eine String-Eigenschaft (SQL.Text) mehrfach gesetzt wird oder nicht sollte von der Geschwindgkeit unter den Tisch fallen...

dataspider 2. Jan 2017 13:27

AW: SQL "Update or Insert" langsam
 
Durch die dauernde Zuweisung des Statemants wird die Komponente jedes mal ein Unprepare schicken.
Dadurch geht der Vorteil der Parameter natürlich flöten...

Frank

jobo 2. Jan 2017 13:47

AW: SQL "Update or Insert" langsam
 
Ggf im SQL das Matching oder andere "Hilfsmittel" ergänzen. Auch wenn es dann doppeltgemoppelt ist, könnte es dem Optimizer eine Hilfestellung sein.
Ohne weiteres wirkt ja ein Update erstmal auf den gesamten Datenbestand, ist also eine fette Nummer.
Wirklich flott ist wahrscheinlich eine komplette Umstellung auf:
Step1:
Insert into <table> (<fields>)
select <values> from table
where not exists .. (bzw. in richtig mit self join und is null Prüfung)
Step2:
Updates mit ähnlichem Vorgehen.

Wäre die Frage, ob es ständig geschieht und nervt oder die bequeme Formulierung oben eine einmalige Sache ist und mit ein paar Tränchen verdrücken zu bewältigen ist.

mkinzler 2. Jan 2017 14:07

AW: SQL "Update or Insert" langsam
 
Zitat:

Zitat von BlueStarHH (Beitrag 1357739)
Zitat:

Zitat von DeddyH (Beitrag 1357737)
Wieso setzt Du innerhalb der Schleife jedesmal die SQL-Eigenschaft neu? Und fehlt da nicht ein MATCHING in Deinem Statement?

Pseudocode ;-) Die Schleife und der Inhalt sind im echten Code ganz weit von einander weg und entkoppelt, dass es nur so geht. Ich kann nur den Inhalt in der Schleife kontrollieren. Ob da nun eine String-Eigenschaft (SQL.Text) mehrfach gesetzt wird oder nicht sollte von der Geschwindgkeit unter den Tisch fallen...

Nein. Absolut nicht, weil man dann den Vorteil der Parameter nicht hat

Delphi-Quellcode:
Transaction.StartTransaction;

Query.SQL.Text := 'Update or insert into foo (A, B, C) values (:a, :b, :c)';
for i := 0 to 2000 do
begin
  Query.ParamByName('a').AsString := 'v1';
  Query.ParamByName('b').AsString := 'v2';
  Query.ParamByName('c').AsString := 'v3';
  Query.Execute;
end;

Transaction.Commit;

Mikkey 2. Jan 2017 14:58

AW: SQL "Update or Insert" langsam
 
Zitat:

Zitat von mkinzler (Beitrag 13577499)
Delphi-Quellcode:
Transaction.StartTransaction;

Query.SQL.Text := 'Update or insert into foo (A, B, C) values (:a, :b, :c)';
for i := 0 to 2000 do
begin
  Query.ParamByName('a').AsString := 'v1';
  Query.ParamByName('b').AsString := 'v2';
  Query.ParamByName('c').AsString := 'v3';
  Query.Execute;
end;

Transaction.Commit;

Noch ein Vorschlag zur Beschleunigung:
Delphi-Quellcode:
Transaction.StartTransaction;

Query.SQL.Text := 'Update or insert into foo (A, B, C) values (:a, :b, :c)';
ParamA = Query.ParamByName('a');
ParamB = Query.ParamByName('b');
ParamC = Query.ParamByName('c');
for i := 0 to 2000 do
begin
  ParamA.AsString := 'v1';
  ParamB.AsString := 'v2';
  ParamC.AsString := 'v3';
  Query.Execute;
end;

Transaction.Commit;
Erspart auch noch dreimal pro Runde das Auswerten von ParamByName.

user0815 2. Jan 2017 15:39

AW: SQL "Update or Insert" langsam
 
Delphi-Quellcode:
Transaction.StartTransaction;

Query.SQL.Text := 'Update or insert into foo (A, B, C) values (:a, :b, :c)';

Query.Params[0].DataType := ftString;
Query.Params[1].DataType := ftString;
Query.Params[2].DataType := ftString;

for i := 0 to 2000 do
begin
  Query.Params[0].Value := 'v1';
  Query.Params[1].Value := 'v2';
  Query.Params[2].Value := 'v3';
  Query.Execute;
end;

Transaction.Commit;
geht es nicht auch so?
Erspart das Auswerten & Überprüfen des Typs sowie das Suchen der Parameter Position.

hoika 2. Jan 2017 20:43

AW: SQL "Update or Insert" langsam
 
Hallo,
bei IBDAC muss man explizit preparen, um Parameter ausnutzen zu können

Delphi-Quellcode:
Transaction.StartTransaction;

Query.SQL.Text := 'Update or insert into foo (A, B, C) values (:a, :b, :c)';

// das fehlte
Query.Prepare;

for i := 0 to 2000 do
begin
  Query.ParamByName('a').AsString := 'v1';
  Query.ParamByName('b').AsString := 'v2';
  Query.ParamByName('c').AsString := 'v3';
  Query.Execute;
end;

Transaction.Commit;
Und dem Link von SProske zufolge spielt auch der Primary Key eine Rolle,
wie sieht denn die Tabellenstruktur aus?


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:37 Uhr.
Seite 1 von 3  1 23   

Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf