![]() |
Datenbank: Interbase • Version: 6 • Zugriff über: IBX
Wöchentlich etliche Datensätze updaten
Hallo liebe Delphianer,
ich muß wöchentlich Daten in meiner Datenbank aktualisieren / updaten. Ich bekomme eine CSV Datei mit 6,7 Milionen Datensätze. Aus diesen suche ich ca. 650.000 Datensätze heraus und mache ein Update bzw. Insert. Das ganze mach ich mitteles eines Delphi 7 Programmes und die IBX Komponeten. Es läuft alles in einer Schleife.
Delphi-Quellcode:
Das ganze mache ich mitteles vier IBQuerys. Vor der Schleife habe ich für die drei Querys natürlich ein Prepare gemacht. Der Commit mache ich am Schluß nach der Schleife. Auf jedem den drei Felder welche für den Vergleich benötigt wird liegt ein eigenen Index.
1.) Prüfen, ob Daten benötigt werden oder nicht. Dadurch werden aus den 6,7 Milionen schon mal "nur" noch 650.00.
2.) Prüfen, ob Daten schon in der Datenbank vorhanden sind anhand von einen Vergleich von drei Feldern mittels eines Select wenn ja-> 2.1 wenn nein -> 2.2 2.1) Mittes Update die Daten auf den neuesten Stand bringen und aktuelles Datum in ein Feld schreiben. -> 3 2.2) Mittes Insert die Daten in die Datenbank importieren und aktuelles Datum in ein Feld schreiben. -> 3 3.) Pürfen auf Datensätze ohne aktuelles Datum und diese dann löschen. Nun aber zu meinen Problem. Das ganze funktioniert natürlich dauert jedoch > 10 Stunden. Gibt es hier einen andere Möglichkeit für mich dieses schneller zu erledigen ? :gruebel: :glaskugel: Danke Dumpfbacke. |
Re: Wöchentlich etliche Datensätze updaten
Ich würde das über eine Stored Procedure machen und diese mit den Daten füttern. Die Procedure wird direkt auf dem Server ausgeführt.
|
Re: Wöchentlich etliche Datensätze updaten
Ich würde auch an ein Update des DBServers denken ( FireBird >= 2.1) und es dann mit eine
SQL-Code:
machen
update or insert
|
Re: Wöchentlich etliche Datensätze updaten
Einen schönen Guten Morgen,
mir scheinen da 10 Stunden nicht zu viel zu sein, Frage mich jedoch wo die Zeit bleibt (Mein Orakel weiss da grad auch nichts). Könntest Du mal die Zeiten messen, welche a) für die Aufbereitung und Auswahl der Datensätze benötigt wird b) %tualen Anteil der Inserts und %tualen Anteil der Zeit und die Absolut benötigte Zeit c) wie (b) nur für die Updates d) für das Prüfen und Löschen der Datensätze Denke, dann sehen wir schon etwas klarer wo wir hier am besten ansetzen sollten. Schöne Grüße OREADEN |
Re: Wöchentlich etliche Datensätze updaten
Zitat:
Mit den Stored Procedures werde ich mal testen ob es etwas bringt. Dumpfbacke |
Re: Wöchentlich etliche Datensätze updaten
Zitat:
|
Re: Wöchentlich etliche Datensätze updaten
Zitat:
Habe ich hier villeicht ein Fehler bei der Stored Produre gemacht oder warum ist die denn so langsam ? Hier mal die Procedure
Delphi-Quellcode:
CREATE PROCEDURE DatenUpdate ( Feld1 varchar(20) character set iso8859_1, Feld2 varchar(4) character set iso8859_1, Feld3 varchar(35) character set iso8859_1, Feld4 varchar(20) character set iso8859_1, Feld5 varchar(10) character set iso8859_1, Feld6 varchar(50) character set iso8859_1, Feld7 varchar(30) character set iso8859_1) as declare variable maxZaehler integer; declare variable zaehler integer; declare variable dsgefunden integer; begin /* Procedure Text */ for Select Max(Tabelle1Zaehler) From Tabelle1 into :maxZaehler do DSGefunden = 0; Zaehler = 0; for Select Tabelle1Zaehler From Tabelle1 Where (Feld1 = :Feld1) and (Feld2 = :Feld2) and (Feld5 = :Feld5) into :Zaehler do begin DSGefunden = 1; end if (DSGefunden = 1) then begin update Tabelle1 set Tabelle1ZAEHLER = :Zaehler, Feld1 = :Feld1, Feld2 = :Feld2, Feld3 = :Feld3, Feld4 = :Feld4, Feld5 = :Feld5, Feld6 = :Feld6, Feld7 = :Feld7, AKTUELLESDATUM = current_date where Tabelle1ZAEHLER = :Zaehler; /*Test = 'update';*/ Suspend; end else begin maxZaehler = maxZaehler +1; insert into Tabelle1 (Tabelle1ZAEHLER, Feld1, Feld2, Feld3, Feld4, Feld5, Feld6, Feld7, AKTUELLESDATUM) values (:maxZaehler, :Feld1, :Feld2, :Feld3, :Feld4, :Feld5, :Feld6, :Feld7, current_date); /*Test = 'insert';*/ Suspend; end end^ SET TERM ; ^ |
Re: Wöchentlich etliche Datensätze updaten
Ich würde eine SP erzeugen, welche alle Datensätze updatet nicht nur einen
|
Re: Wöchentlich etliche Datensätze updaten
Ist das tatsächlich die SP, mit der Du inserten/updaten wolltest?
Ich hab mal ein wenig formatiert und ein paar Anmerkungen dazugeschrieben.
SQL-Code:
Hier eine SP, die alle Datensätze, bei denen die Felder 1,2 und 5 übereinstimmen updated und einen neuen Datensatz einfügt, wenn keine Übereinstimmung gefunden wurde.
CREATE PROCEDURE DatenUpdate (
Feld1 varchar(20) character set iso8859_1, Feld2 varchar(4) character set iso8859_1, Feld3 varchar(35) character set iso8859_1, Feld4 varchar(20) character set iso8859_1, Feld5 varchar(10) character set iso8859_1, Feld6 varchar(50) character set iso8859_1, Feld7 varchar(30) character set iso8859_1) as declare variable maxZaehler integer; declare variable zaehler integer; declare variable dsgefunden integer; begin for Select Max(Tabelle1Zaehler) From Tabelle1 into :maxZaehler do DSGefunden = 0; /* for select ist hier unsinnig, es wird immer wenn die Tabelle mindestens einen Datensatz enthät der höchste Wert von Tabelle1Zaehler zurückgegeben und DSGefunden auf 0 gesetzt. Andernfalls sind beide Werte undefiniert. */ Zaehler = 0; for Select Tabelle1Zaehler From Tabelle1 Where (Feld1 = :Feld1) and (Feld2 = :Feld2) and (Feld5 = :Feld5) into :Zaehler do begin DSGefunden = 1; /* hier wird für jeden gefundenen Datensatz DSGefunden auf 1 gesetzt*/ end if (DSGefunden = 1) then begin update Tabelle1 set Tabelle1ZAEHLER = :Zaehler, Feld1 = :Feld1, Feld2 = :Feld2, Feld3 = :Feld3, Feld4 = :Feld4, Feld5 = :Feld5, Feld6 = :Feld6, Feld7 = :Feld7, AKTUELLESDATUM = current_date where Tabelle1ZAEHLER = :Zaehler; /* hier wird nun der letzte gefundene Datensatz aktualisiert */ /* Suspend --> raus damit, hat in einer SP ohne Rückgebewert nichts verloren */ end else begin /* Wenn DSGefunden != 1 und not null */ maxZaehler = maxZaehler +1; insert into Tabelle1 (Tabelle1ZAEHLER, Feld1, Feld2, Feld3, Feld4, Feld5, Feld6, Feld7, AKTUELLESDATUM) values (:maxZaehler, :Feld1, :Feld2, :Feld3, :Feld4, :Feld5, :Feld6, :Feld7, current_date); /* neuen Datensatz einfügen */ /* Suspend --> raus damit, hat in einer SP ohne Rückgebewert nichts verloren */ end end
SQL-Code:
SP ist ungetestet, nur ins Unreine geschrieben.
CREATE PROCEDURE DatenUpdate (
Feld1 varchar(20) character set iso8859_1, Feld2 varchar(4) character set iso8859_1, Feld3 varchar(35) character set iso8859_1, Feld4 varchar(20) character set iso8859_1, Feld5 varchar(10) character set iso8859_1, Feld6 varchar(50) character set iso8859_1, Feld7 varchar(30) character set iso8859_1) as declare variable anz integer; declare variable zaehler integer; begin anz = 0; select count (*) from Tabelle1 where (Feld1 = :Feld1) and (Feld2 = :Feld2) and (Feld5 = :Feld5) into :anz; if (:anz > 0) then begin update Tabelle1 set Feld3 = :Feld3, Feld4 = :Feld4, Feld6 = :Feld6, Feld7 = :Feld7, AKTUELLESDATUM = current_date where (Feld1 = :Feld1) and (Feld2 = :Feld2) and (Feld5 = :Feld5); end else begin Select Max(Tabelle1Zaehler) From Tabelle1 into :Zaehler; if (:zaehler is null) then zaehler = 1; else zaehler = :zaehler + 1; insert into Tabelle1 (Tabelle1ZAEHLER, Feld1, Feld2, Feld3, Feld4, Feld5, Feld6, Feld7, AKTUELLESDATUM) values (:maxZaehler, :Feld1, :Feld2, :Feld3, :Feld4, :Feld5, :Feld6, :Feld7, current_date); end end Anmerkung zur Performance:
Hoffe, das hilft Dir weiter. |
Re: Wöchentlich etliche Datensätze updaten
Zitat:
Und den Query Plan mal prüfen (diesen kann man bei den IBX-Query-Komponenten netterweise gleich über eiine Funktion abfragen), ob dort auffällige Joins auftauchen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:13 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 by Thomas Breitkreuz