![]() |
Datenbank: Firebird • Version: 2.5 • Zugriff über: ADO und ODBC
Anfängerfrage zu SQL-Insert
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:
Funktioniert super, braucht aber leider rund 20 Minuten. ;-) Ich schätze mal, das geht schneller, nur wie?
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; 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 |
AW: Anfängerfrage zu SQL-Insert
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, ![]() wenn da was auf dem system der grund sein sollte, warum firebird da so lahm ist wirst du das auf dem weg merken |
AW: Anfängerfrage zu SQL-Insert
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 |
AW: Anfängerfrage zu SQL-Insert
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 |
AW: Anfängerfrage zu SQL-Insert
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:
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.
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; Nach Backup + Restore war alles wieder schnell wie bisher. |
AW: Anfängerfrage zu SQL-Insert
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. |
AW: Anfängerfrage zu SQL-Insert
Zitat:
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 ...) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:03 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz