AW: 100.000 Datensätze in 22 Minuten - geht das noch schneller?
Nein, dann verliert man den Vorteil des Prepare und bei jedem Insert muss in neuer Plan generiert werden.
|
AW: 100.000 Datensätze in 22 Minuten - geht das noch schneller?
Zitat:
Bei 100000 bedeutet das 200000 Operationen, bei denen nur die Hälfte erfolgreich ist und dort zu einem gewissen Anteil dann noch reihenweise Pk Verletzungen auftreten. Wahrscheinlich ist das nicht besonders schnell. |
AW: 100.000 Datensätze in 22 Minuten - geht das noch schneller?
Jedes Statements nacheinander einzeln auszuführen ist erheblich langsamer, da die Ausführung jedes einzelnen Befehls erst einmal vom Server bestätigt werden muss, bevor der nächste gesendet wird. Das Script kann für jeden Datensatz die Procedur aufrufen, die von Fall zu Fall Update oder Insert ausführt.
Prepare bietet zwar bei komplizierten Abfagen Vorteile, dürfte hier aber keine große Rolle spielen. |
AW: 100.000 Datensätze in 22 Minuten - geht das noch schneller?
Aufgrund mehrerer Anfragen, die ich in den letzten Tagen eh zu dem Thema bekommen hatte, habe ich gerade mal ein Tutorial zusammengestellt, das euch hoffentlich weiterhilft. Das ganze ist zwar in englischer Sprache, aber trotzdem recht simpel gehalten. Basis ist Firebird 2.5 und IBExpert, aber die IBExpert Teile lassen sich auch mit anderen Tools erledigen, wenn auch vielleicht weniger komfortabel. Für den Konvertierungsteil kann man auch problemlos Delphi einsetzen. Das Tutorial darf auch gerne auf anderen Foren veröffentlich werden, sofern die Inhalte unverändert sind, von üblichen Rechtsschreibfehlern mal abgesehen. In den nächsten Tagen wird das auch noch bei uns auf die Webseite eingearbeitet.
In dem Beispiel zeige ich Schritt für Schritt, wie man 100000 Datensätze aus einer csv Datei in 21 Sekunden importiert und verarbeitet, das sind eher die Werte, mit denen man rechnen sollte. 22 Minuten gehen da ja nahtlos in Lieferzeiten über, da wird dann schnell mal die Nacht zu kurz. Kommentare gerne hier in der Delphipraxis oder auch direkt per email an mich: hklemt at ibexpert punkt com http://www.ibexpert.com/download/Imp...portExport1.7z p.s.: Ich hätte das auch hier hochgeladen, ging aber irgendwie nicht, trotz 4,2 MB. Nun denn, evtl. wird ja ein Moderator ein passendes Plätzchen finden |
AW: 100.000 Datensätze in 22 Minuten - geht das noch schneller?
[Klugsch***]
Was der Holger da gemacht hat, beschreibt sich kurz so: Die CSV-Daten werden in das Firebird-External-Table-Format gewandelt und dann direkt in die DB als Tabelle "eingehangen". Das geht wirklich wahnsinnig schnell und wir nutzen das schon einige Zeit im produktiven Umfeld. [/Klugsch***] Weil ich den Tip von ihm schon mal vor einiger Zeit bekommen habe, habe ich damals ne Delphi-Klasse dafür geschrieben. Wer also keinen IBExpert hat (mein Mitleid) kann diese Unit probieren. Mit dieser Klasse kann man einen Datensatz generieren. Danach kann man ihn z.B. in einen Filestream schreiben. Dann noch Reset aufrufen und schon gehts von vorne los. Bitte beachtet den Kommentar am Anfang der Datei. Wenn einer eine Lösung kennt, sagt bitte Bescheid. //edit: So, nach ein wenig Suche&Finde sehe ich jetzt ein, das das External-Table-Format so lange gut ist, so lange man mit char-Felder arbeitet. Alles andere ist zu Prozessor/ODS-abhängig. |
AW: 100.000 Datensätze in 22 Minuten - geht das noch schneller?
Das sollte mit BULK INSERT unter SQL-Server auch sehr schnell gehen. Danach kann man mit ein paar Befehlen auf einmal einfügen bzw. überschreiben.
|
AW: 100.000 Datensätze in 22 Minuten - geht das noch schneller?
100000 Datensätze mit Firebird
Ein schönes, ausführliches Beispiel, trotzdem ein paar Anmerkungen. Ich hab das mit external table unter oracle ausprobiert. Gleiche Daten, gleiches Verfahren. Unterschied war nur, dass es mit rawdata.csv direkt, also delimited gelaufen ist. Dabei bin ich auf ca 5 Minute Laufzeit via insert/update stored proc gekommen. Aufgefallen ist mir, dass der Update Fall gar nicht eintritt, alles verschiedene IDs in rawdata.csv Die Firebird Zeiten von 22 sec wundern mich aber schon etwas. Sind die wirklich mit der Stored Proc aus dem Tutorial gemessen? Ein reines Insert- ohne SP- (was bei den Daten ja ok gewesen wäre, weil keine doppelten ID) dauert in meinem Test unter 2 Sekunden, was mir relativ plausibel erscheint, da die Zieltabelle aus dem Tutorial keinen Primärschlüssel / Index hat. Genau das wäre für mich auch der Grund für ein wesentlich länger dauerndes Insert/Update mittels satzweiser Stored Proc. 100000 mal ID suchen fürs Update ohne Index dauert halt. Wenn das bei Firebird wirklich so schnell geht, sollte ich mich vielleicht mehr damit beschäftigen! :) Und was ich gar nicht verstehe: Wenn man schon extra alles rüber schaufelt auf den Server -was ich ja gut finde- und direkt per SQL auf externe Daten zugreifen kann, wieso dann trotzdem satzweise importieren? Wieso nicht eine Updateanweisung und eine Insertanweisung für alles? Oder geht so ein Update in Firebird nicht? |
AW: 100.000 Datensätze in 22 Minuten - geht das noch schneller?
Hier mal das ganze mit MySQL:
Leere Tabelle Zitat:
Zitat:
Code:
CREATE TABLE `tblimport` (
`ID` int(11) NOT NULL, `CATEGORY_ID` int(11) NOT NULL, `TITLE` varchar(100) DEFAULT NULL, `ACTOR` varchar(100) DEFAULT NULL, `PRICE` decimal(10,2) NOT NULL, `SPECIAL` int(11) NOT NULL, PRIMARY KEY (`ID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
AW: 100.000 Datensätze in 22 Minuten - geht das noch schneller?
Zitat:
|
AW: 100.000 Datensätze in 22 Minuten - geht das noch schneller?
Zitat:
Wie gesagt, Insert hat bei mir unter 2 sec gedauert, update ca 0 sec, es gab ja keine. Merge habe ich nicht probiert.
Code:
for
select ID, CATEGORY_ID, TITLE, ACTOR, PRICE, SPECIAL from IMPORT_PRODUCT into :ID, :CATEGORY_ID, :TITLE, :ACTOR, :PRICE, :SPECIAL do begin --is this record already there? select count(*) from product where product.id=:id into :cnt; if (cnt=0) then begin --no, so do an insert insert into PRODUCT (ID, CATEGORY_ID, TITLE, ACTOR, PRICE, SPECIAL) values (:ID, :CATEGORY_ID, :TITLE, :ACTOR, :PRICE, :SPECIAL); end else begin --yes, so update the record update PRODUCT set CATEGORY_ID = :CATEGORY_ID, TITLE = :TITLE, ACTOR = :ACTOR, PRICE = :PRICE, SPECIAL = :SPECIAL where (ID = :ID); end end --thats all |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:11 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