1.1k Aufrufe
Gefragt in Skripte(PHP,ASP,Perl...) von
Hallo,

ich steh vor einem großen Problem: Ich habe eine CSV-Datei mit ca. 20.000 Zeilen. Eine Spalte einer Zeile beinhaltet immer eine E-Mail-Adresse.

In der Datenbank hab ich ebenso ein Feld mit der E-Mail-Adresse, hier liegt auch ein Index drauf.

Mein Vorhaben: Den Wert eines bestimmten Feldes update für den Datensatz mit der E-Mail, die in der CSV-Datei vorkommt. Beispiel:
in der CSV-Datei ist die E-Mail test@test.de vorhanden. In der Datenbank muss ich nun für diese E-Mail den Wert setzen. Der Wert den ich setze, ist immer der gleiche. Nur wie kann ich das am performantesten machen?

Möglichkeit 1 bricht bei mir immer ab mit einem Browser(!)-Fehler:
ich habe alle Emails der CSV-Datei in ein Array gelesen und geh in einer Schleife über alle Datensätze in der DB, die in Frage kommen für ein Update (sind aber leider immer noch ca 91.000).
mit array_key_exists prüfe ich, ob die Email im array vorhanden ist (email ist schlüssel im array) und führe dann das update durch. Hierfür nutze ich auch schon prepared Statements.
WIe gesagt, dauert das aber zu lange und bricht irgendwann ab. Momentan kann ich grad mal 100 Datensätze updaten.

Das Problem ist nämlich. dass ich jede E-Mail nur einmal updaten darf. Beispiel: die E-Mail test@test.de ist 5x in der Datenbank vorhanden, der erste Eintrag darf nur ein Update erhalten.

Wie kann ich das am geschicktesten lösen?

Ich hatte gedacht, ich packe alle Emails in einen String, kommagetrennt, den ich beim Update dann in der Where-Klausel mitgeben über "IN (emails...)". Aber 20.000 emails im where geht nicht gut oder? außerdem werden dann alle datensätze geupdatet...

Ich bin ratlos :-(

3 Antworten

0 Punkte
Beantwortet von
Gerade wenn ich verschiedene Datenquellen habe und diese Kreuz und Quer rumschiebe nutze ich immer "Microsoft Access" dort kannst du deine geforderten Wünsche alle Problemlos umsetzen. Du holst dir einfach die CSV und die Datenbank als verküpfte Tabelle rein und legst eine Abfrage an mit deinen Bedinungen, fertig.

Viel Spaß, hoffe es hat geholfen.
0 Punkte
Beantwortet von son_quatsch Experte (5.3k Punkte)
Beispiel: die E-Mail test@test.de ist 5x in der Datenbank vorhanden, der erste Eintrag darf nur ein Update erhalten.
Und welche davon ist die "erste"? Ohne weiteren Index oder ohne weiteres Sortierkriterium ist überhaupt nicht vorhersagbar, welche der E-Mails als "erste" gilt.

Möglichkeit 1 bricht bei mir immer ab mit einem Browser(!)-Fehler
Nun, wenn wir z.B. von PHP sprechen, werden mögliche Fehler immer im Browser ausgegeben...

Am besten fügst du hier mal dein bisheriges Skript ein - und benutz den Code-Button.
0 Punkte
Beantwortet von
Hallo,

danke für die Antworten. Allerdings hab ich das Problem schon gelöst...gott sei dank :-)

Trotzdem will ich noch kurz die Fragen beantworten:

Um zu prüfen, ob ich die "erste" Email grad in der Schleife habe, habe ich mir das Ergebnis per ID aufsteigend sortieren lassen. Das heißt, die erste Email bearbeite ich auch als erstes. Jede Email, die ich schon bearbeitet hab, packe ich in ein Array und prüfe beim nächsten Durchgang, ob die Email schon vorhanden ist oder nicht. Das mit dem Sortieren hätte ich vielleicht noch erwähnen sollen...

Der Fehler war komischerweise kein typischer PHP-Fehler, sondern vom Server selbst. Es war folgender:


Serverfehler!

Die Anfrage kann nicht beantwortet werden, da im Server ein interner Fehler aufgetreten ist.

Fehlermeldung:
Premature end of script headers: php-fcgi-starter

Sofern Sie dies für eine Fehlfunktion des Servers halten, informieren Sie bitte den Webmaster hierüber.

Error 500


gelöst hab ich das Problem wie folgt: ich hab mir angeschaut, was bei dem Script am längste gedauert hat, und das war die SQL-Abfrage, mit der ich jeden Datensatz gegenprüfe. Dabei ist mir aufgefallen, dass komplette Table-Scans von der DB durchgeführt werden mussten. Also hab ich einen Index auf die entsprechende Spalte gesetzt - und siehe da, das Script lief in knapp 5-10 Sekunden durch :-)
...