AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Anfängerfrage zu SQL-Insert
Thema durchsuchen
Ansicht
Themen-Optionen

Anfängerfrage zu SQL-Insert

Ein Thema von Marco Steinebach · begonnen am 24. Feb 2021 · letzter Beitrag vom 25. Feb 2021
Antwort Antwort
Marco Steinebach

Registriert seit: 4. Aug 2006
502 Beiträge
 
Delphi 5 Enterprise
 
#1

Anfängerfrage zu SQL-Insert

  Alt 24. Feb 2021, 20:21
Datenbank: Firebird • Version: 2.5 • Zugriff über: ADO und ODBC
Hallo zusammen,
Blöde DB-Anfängerfrage.
Mit folgendem Code möchte ich meine Datenbank füllen, ca. 2000 Datensätze, knapp 30 Spalten.
Code:
adoConnection1.loginprompt := false;
adoConnection1.connectionString := 'bla';
adoConnection1.connected := true;
adoCommand1.connection := adoConnection1;
for i := 0 to 2000 do
begin
  adoCommand1.commandText := 'insert into bla values (1, 2, 3);';
adoCommand1.execute;
end;
adoConnection1.connecgted := false;
Funktioniert super, braucht aber leider rund 20 Minuten. Ich schätze mal, das geht schneller, nur wie?
Ich denke, da er, bei meinem Code, jedesmal eine neue Transaktion startet dauert das so ewig lange.

Für einen Schups wäre ich sehr dankbar.

Herzlich grüßt
Marco
Marco Steinebach
  Mit Zitat antworten Zitat
Benutzerbild von IBExpert
IBExpert

Registriert seit: 15. Mär 2005
671 Beiträge
 
FreePascal / Lazarus
 
#2

AW: Anfängerfrage zu SQL-Insert

  Alt 24. Feb 2021, 20:39
ich hab nie freiwillig mit ado gearbeitet, aber 20 minuten ist ja gruselig, ich würde 20 sekunden
schon hinterfragen.

daher

sidn irgendwelche trigger auf deiner tabelle? wenn ja, schalte die ggf mal ab
oder zeig mal die metadaten der datenbank für diese tabelle
(in ibexpert zB das was im ddl reiter zu sehen ist)

20 minuten lassen sich auch durch extra transaktionen nicht erklären, aber ggf such mal
ob die adoConnection1. irgendwas hat wie adoConnection1.starttransaction
oder adoConnection1.commit oder adoConnection1.transaction ....

ggf kannst du auch mal auf dem firebird server einen ibexpert benchmark
laufen lassen, https://www.ibexpert.com/benchmark

wenn da was auf dem system der grund sein sollte, warum firebird da so lahm
ist wirst du das auf dem weg merken
Holger Klemt
www.ibexpert.com - IBExpert GmbH
Oldenburger Str 233 - 26203 Wardenburg - Germany
IBExpert and Firebird Power Workshops jederzeit auch als Firmenschulung
  Mit Zitat antworten Zitat
knuut21

Registriert seit: 3. Mär 2010
Ort: Unna
21 Beiträge
 
RAD-Studio 2010 Ent
 
#3

AW: Anfängerfrage zu SQL-Insert

  Alt 24. Feb 2021, 21:28
Ich könnte mir vorstellen, dass dein Beispiel implizit eine Transaktion startet und nach dem Insert implizit ein commit ausgeführt wird. Wenn du vor der Schliefe eine Transaktion explizit startest und am Ende der Schleife die Transaktion comittest, sollte es deutlich schneller gehen.

BG
  Mit Zitat antworten Zitat
Marco Steinebach

Registriert seit: 4. Aug 2006
502 Beiträge
 
Delphi 5 Enterprise
 
#4

AW: Anfängerfrage zu SQL-Insert

  Alt 24. Feb 2021, 22:49
Huhu,
Hab ich auch schon gedacht, es gibt zwar ein BeginTrans und CommitTrans, aber da ändert sich nix.
Wenn ich die Source richtig gelesen habe, interessiert das AdoCommand auch nicht wirklich...

Herzlich grüßt
Moo
Marco Steinebach
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.492 Beiträge
 
Delphi 7 Enterprise
 
#5

AW: Anfängerfrage zu SQL-Insert

  Alt 24. Feb 2021, 23:30
Ich hab mal eine Messuung vorgenommen, das sind 201 ms bei mir. Verbindung über ODBC mit ADO.
Delphi-Quellcode:
object ADOConnection1: TADOConnection
  ConnectionString =
    'Provider=MSDASQL.1;Password=masterkey;Persist Security Info=True' +
    ';User ID=SYSDBA;Data Source=Firebird Test'
  LoginPrompt = False
  Provider = 'MSDASQL.1'
end
Delphi-Quellcode:
var
  I : Integer;
  Sw : TStopWatch;
begin
  adoConnection1.connected := true;
  adoCommand1.connection := adoConnection1;

  adoCommand1.commandText := 'create table bla (one integer, two integer, three integer)';
  adoCommand1.execute;
  Sw.Start;
  for i := 0 to 2000 do
  begin
    adoCommand1.commandText := 'insert into bla values (1, 2, 3);';
    adoCommand1.execute;
  end;
  Sw.Stop;
  ShowMessageFmt('Dauer %d ms', [Sw.Elapsed.Milliseconds]);

  adoCommand1.commandText := 'drop table bla';
  adoCommand1.execute;
end;
Bei vielen nicht korrekt abgeschlossenen Transkationen (z.b. killen des Prozesses beim Debgging) macht Firebird generell schwerste Probleme. Ich hatte gerade letzte Woche den Fall, dass ein Datenimport (640.000 Inserts mit 19 Feldern) anstelle von bisher 5 Minuten 6 Stunden benötigte.

Nach Backup + Restore war alles wieder schnell wie bisher.
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all

Geändert von Union (24. Feb 2021 um 23:40 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.354 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Anfängerfrage zu SQL-Insert

  Alt 25. Feb 2021, 07:46
Bist du sicher, dass der Flaschenhals beim Insert ist?
Du hast den Source teilweise manuell eingetippt. So wie er da steht, würde er nicht mal compiliert. Wir wissen auch nicht, wie du die Datensätze für das Insert zusammen stellst. Auch da kann ein Flaschenhals sein.

Hat deine Zieltabelle vielleicht viele Indexe oder Constraints?
Liegt die Datenbank bei dir lokal oder ist die auf einem anderen Rechner/Server oder sogar im Internet? -> Leitungsprobleme
Prüft dein Antiviren-Programm jede Dateiveränderung? -> Vielleicht mal für einen Test ausschalten.
Wie oben schon geschrieben: Dauert die Bereitstellung der Quelldaten vielleicht lange?

Hast du schon den Debugger benutzt? Eine halbe Sekunde pro Datensatz würdest du beim Debuggen sicher bemerken, wenn es nur durch eine Befehlszeile passiert.
Peter
  Mit Zitat antworten Zitat
Benutzerbild von IBExpert
IBExpert

Registriert seit: 15. Mär 2005
671 Beiträge
 
FreePascal / Lazarus
 
#7

AW: Anfängerfrage zu SQL-Insert

  Alt 25. Feb 2021, 09:15
Bei vielen nicht korrekt abgeschlossenen Transkationen (z.b. killen des Prozesses beim Debgging) macht Firebird generell schwerste Probleme. Ich hatte gerade letzte Woche den Fall, dass ein Datenimport (640.000 Inserts mit 19 Feldern) anstelle von bisher 5 Minuten 6 Stunden benötigte.

Nach Backup + Restore war alles wieder schnell wie bisher.
Nicht FIrebird macht da schwerste Probleme, sondern wie fast immer derjenige, der an der Tastatur sitzt oder das Werkzeug, was der da benutzt.

Und ja, Transaktionen lange offen halten ist immer eine blöde idee, 5 minuten auf 6 Stunden bringen erfordert aber weit mehr als irgendwann
mal im debugging abgebrochen zu haben, wenn das problem an firebird liegen sollte. Und ich bin mir ziemlich sicher, das ein Blick in die MON$
Tabellen gezeigt hätten, welche Transaktionen da ggf. das Problem ausgelöst haben und ein ganz simpler delete from mon$attachment oder den
dienst neu starten hätte auch gereicht.

Was ado oder die Komponente da veranstaltet oder warum bei euch der firebird so lahm ist, kann man per ferndiagnose natürlich schlecht sagen, aber ein weg das
zu beschleunigen ist eben wenn das mal auftritt beim Entwickler, einfach mal den Dienst neu starten, am besten aber vorher noch in mon$attachments
und mon$transactions reinschauen oder in ibexpert auf services-database monitoring in die gleichen bereichen (dort könnt ihr hängende
Transaktionen auch gleich beenden).

Und als weiterer Tip noch mal: prüft mal mit dem Benchmark wie schnell eure Maschine mit Firebird ist

und noch was, stell um auf parametrisierte queries (keine ahnung ob ado commandtext das kann, wenn nicht, dann mach das besser gleich richtig und nehm native komponenten, mit denen das geht

//sql wird außerhalb der schleife nur ein mal gesetzt
adoCommand1.commandText := 'insert into bla values (:p1, :p2, :p3);';
//falls es das gibt, mach ein prepare
adoCommand1.prepare;
Sw.Start;
for i := 0 to 2000 do
begin
//innerhalb der schleife dann nur noch parameter zuweisen
adoCommand1.parambyname('p1').AsInteger:=i+1;
adoCommand1.parambyname('p2').AsInteger:=i+2;
adoCommand1.parambyname('p3').AsInteger:=i+3;
adoCommand1.execute;
end;
Sw.Stop;


und wie schon gesagt, versuch nicht mit irgendwelchen ungeeigneten Komponenten überhaupt erst deinen Quelltext aufzubauen, die umstellung nachher auf performante Versionen lässt sich vermeiden, in dem man gar nicht erst mit ungeeignetem Kram anfängt.

Und wie schon gesagt, wenn du beispiele hier postest, ergänzen dein ddl und mach nicht irgendwelche umgestellten bla bla beispiele, oft sind kleine details der Grund, tabelle ohne indizes, ohne primary keys, dafür aber mit endlos triggerversuchen zB verlieren die zeit ganz woanders und nicht in dem Pseudo code.

ich stell die auswahl über ado zu gehen grundsätzlich bei allen delphi versionen in frage, aber vielleicht siehst du dafür ja gründe (man könnte ja mal umstellen wollen auf andere plattformen ist keiner, dann nimm lieber firedac oder ibdac ...)
Holger Klemt
www.ibexpert.com - IBExpert GmbH
Oldenburger Str 233 - 26203 Wardenburg - Germany
IBExpert and Firebird Power Workshops jederzeit auch als Firmenschulung
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:04 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz