Frage zur Eingabe-Effizienz
Frage zur Eingabe-Effizienz
am 24.06.2007 03:23:40 von Tobias Wendorff
Hallo Leute,
ich möchte ca. 2000 Zeilen aus einer CSV-Datei in eine mySQL-Datenbank
eintragen. Da ich jedoch einige Werte verändern muss, kann ich diese
nicht direkt in die Datenbank laden. Ich verwende dazu PHP.
Die 1. Spalte der Datenbank ist ein Datumsfeld (DATEFIELD), gefolgt
von verschiedenen Einzelwerten in den anderen Spalten.
Ich sehe nun zwei Möglichkeiten:
1. Ich lese das Datum und die Zeit aus der CSV-Datei, formatiere sie
nach DATETIME und schreibe sie ins 1. Feld der 1. Reihe (INSERT INTO).
Dann gehe ich die anderen Felder der CSV durch und füge jedes Mal
einen Eintrag zur 1. Reihe dazu (UPDATE). Bei 15 Feldern pro Zeile
wären es also insgesamt 15 Anfragen (1x INSERT, 14x Update).
2. Ich lese das Datum und die Zeit aus der CSV-Datei, formatiere sie
nach DATETIME und schreibe sie und alle anderen Felder in ein Array.
Danach arbeite ich das Array auf einen Schlag ab. Bei 15 Feldern
pro Zeile würde es also nur eine lange INSERT-Anfrage geben.
"Variante 1" belastet also die SQL-Datenbank ziemlich stark.
"Variante 2" zieht viel PHP-Resourcen.
Was würdet ihr verwenden?
Grüße
Tobias
Re: Frage zur Eingabe-Effizienz
am 24.06.2007 08:29:57 von Andreas Kretschmer
Andreas
--
q: why do so many people take an instant dislike to mysql?
a: it saves time (oicu in #postgresql)
Explaining the concept of referential integrity to a mysql user is like
explaining condoms to a catholic (Shadda in #postgresql)
Re: Frage zur Eingabe-Effizienz
am 24.06.2007 10:56:22 von dnoeth
Tobias Wendorff wrote:
> ich möchte ca. 2000 Zeilen aus einer CSV-Datei in eine mySQL-Datenbank
> eintragen. Da ich jedoch einige Werte verändern muss, kann ich diese
> nicht direkt in die Datenbank laden. Ich verwende dazu PHP.
Selber Schuld :-)
Wenn mangels passendem ETL-Tool das Extract-Transform-Load nicht geht,
dann nimmt man ELT (Extract-Load-Transform) mit einer Stagetable:
Lade die Daten 1:1 in eine Zwischentabelle, und mache die Änderungen im
Select-Teil eines Insert/Select in die Zieltabelle. Da sollte immer
effizienter sein als Tausende von einzelnen Inserts/Updates.
Dieter
Re: Frage zur Eingabe-Effizienz
am 24.06.2007 16:16:01 von Tobias Wendorff
Dieter Noeth wrote:
> Lade die Daten 1:1 in eine Zwischentabelle, und mache die Änderungen
> im Select-Teil eines Insert/Select in die Zieltabelle. Da sollte immer
> effizienter sein als Tausende von einzelnen Inserts/Updates.
Dazu müsst ich aber wissen, wo die Änderungen zu machen sind. Aufgrund
der schlechten Datenqualität ist das aber nicht immer vorhersagbar :-(
Re: Frage zur Eingabe-Effizienz
am 24.06.2007 16:17:28 von Tobias Wendorff
Andreas Kretschmer wrote:
> awk und daraus eine COPY-Anweisung machen.
Also im Endeffekt die CSV-Datei "offline" vorbereiten und dann
in die Datenbank kopieren? Stimmt, das klingt total logisch :-)
Re: Frage zur Eingabe-Effizienz
am 24.06.2007 16:20:53 von Claus Reibenstein
Tobias Wendorff schrieb:
> ich möchte ca. 2000 Zeilen aus einer CSV-Datei in eine mySQL-Datenbank
> eintragen.
Mehr nicht?
> 1. Ich lese das Datum und die Zeit aus der CSV-Datei, formatiere sie
> nach DATETIME und schreibe sie ins 1. Feld der 1. Reihe (INSERT INTO).
> Dann gehe ich die anderen Felder der CSV durch und füge jedes Mal
> einen Eintrag zur 1. Reihe dazu (UPDATE). Bei 15 Feldern pro Zeile
> wären es also insgesamt 15 Anfragen (1x INSERT, 14x Update).
Umständlich.
> 2. Ich lese das Datum und die Zeit aus der CSV-Datei, formatiere sie
> nach DATETIME und schreibe sie und alle anderen Felder in ein Array.
> Danach arbeite ich das Array auf einen Schlag ab. Bei 15 Feldern
> pro Zeile würde es also nur eine lange INSERT-Anfrage geben.
Schon wesentlich effektiver.
> "Variante 1" belastet also die SQL-Datenbank ziemlich stark.
> "Variante 2" zieht viel PHP-Resourcen.
So viel PHP-Ressourcen sind das nun auch wieder nicht.
> Was würdet ihr verwenden?
Veriante 3: Du liest die gesamte Datei (oder, falls das nicht geht,
zumindest größere Häppchen) auf einen Rutsch in ein Array, änderst alle
Daten wie gewünscht in diesem Array, am besten schon beim Lesen, und
schreibst sie in einem Rutsch in die Datenbank. Dann reicht ein einziges
INSERT für alle Daten (bzw. für ein Häppchen).
Gruß. Claus
Re: Frage zur Eingabe-Effizienz
am 24.06.2007 16:37:44 von Andreas Kretschmer
Andreas
--
q: why do so many people take an instant dislike to mysql?
a: it saves time (oicu in #postgresql)
Explaining the concept of referential integrity to a mysql user is like
explaining condoms to a catholic (Shadda in #postgresql)
Re: Frage zur Eingabe-Effizienz
am 24.06.2007 18:00:59 von dnoeth
Tobias Wendorff wrote:
>> Lade die Daten 1:1 in eine Zwischentabelle, und mache die Änderungen
>> im Select-Teil eines Insert/Select in die Zieltabelle. Da sollte immer
>> effizienter sein als Tausende von einzelnen Inserts/Updates.
>
> Dazu müsst ich aber wissen, wo die Änderungen zu machen sind. Aufgrund
> der schlechten Datenqualität ist das aber nicht immer vorhersagbar :-(
Und wie machst du es mit PHP, wenn du nicht weisst, was und wo du ändern
musst?
Dieter
Re: Frage zur Eingabe-Effizienz
am 26.06.2007 01:41:53 von Tobias Wendorff
Dieter Noeth wrote:
> Und wie machst du es mit PHP, wenn du nicht weisst, was und wo du
> ändern musst?
Nun, den normalen Weg, wie z.B. mit if-Abfragen oder Switches.
Re: Frage zur Eingabe-Effizienz
am 26.06.2007 08:30:48 von dnoeth
Tobias Wendorff wrote:
>> Und wie machst du es mit PHP, wenn du nicht weisst, was und wo du
>> ändern musst?
>
> Nun, den normalen Weg, wie z.B. mit if-Abfragen oder Switches.
Wenn du ein IF schreiben kannst, dann weisst du doch, wo du ändern musst
und dann kannst du im SQL CASE nehmen, z.B.
insert into target
select
case
when Spalte1 > 15 then mach_was
when andere_bedingung then mach_was_anderes
else Spalte1
end
....
from source
Dieter
Re: Frage zur Eingabe-Effizienz
am 07.07.2007 19:55:30 von Tobias Wendorff
Dieter Noeth wrote:
> Wenn du ein IF schreiben kannst, dann weisst du doch, wo du ändern
> musst und dann kannst du im SQL CASE nehmen, z.B.
> insert into target
> select
> case
> when Spalte1 > 15 then mach_was
> when andere_bedingung then mach_was_anderes
> else Spalte1
> end
> ...
> from source
SQL entwickelt sich irgendwie zu einer eigenen Programmiersprache
für mich :-)(