ich hab ein problem mit der Performance bei der Aktualisierung meiner DB.
Ich bekomme im stundentakt files, die automatisch ich eine DB
eingespeist werden sollen. Soweit kein, das file setzt sich aus
veränderten und neuen einträgen zusammen.
Mein Problem ist nun, wenn bei jedem eintrag im file prüfe ob dieser in
der DB vorhanden ist und ihn dann aktulisiere bzw. neu einfüge ist das
Script iree langsam!
Würde ich die DB mit TRUNCATE leeren und das file einfach jedesmal
komplett in die DB schreiben wäre ich um längen schneller als mit der
UPDATE/INSERT variante!
Mein Script sieht im moment etwa so aus:
while($data as $line){
$result = $db->query("SELECT * FROM dst WHERE id = $line['id']
if($db->rows($result) == 0){
INSERT
} else{
UPDATE
}
}
Es geht hier um > 300.000 einträge und mit jedem Update werden es mehr
einträge! Gibt es nicht eine andere lösung, die Perfomanter ist?
LG Sandro
> while($data as $line){
> $result = $db->query("SELECT * FROM dst WHERE id = $line['id']
> if($db->rows($result) == 0){
> INSERT
> } else{
> UPDATE
> }
> }
Du baust hier etwas in PHP nach, was es in MySQL bereits fertig gibt:
INSERT ... ON DUPLICATE KEY UPDATE.
Gruß. Claus
Besten dank, werd mich gleich damit auseinander setzen!
Ich denke damit sollten meine Performance probleme gelöst sein,
da es auf eine abfrage reduziert wird :) Bin begeistert :)
LG Sandro
> Guten Tag,
>
> ich hab ein problem mit der Performance bei der Aktualisierung meiner DB.
> Ich bekomme im stundentakt files, die automatisch ich eine DB
> eingespeist werden sollen. Soweit kein, das file setzt sich aus
> veränderten und neuen einträgen zusammen.
> Mein Problem ist nun, wenn bei jedem eintrag im file prüfe ob dieser
> in der DB vorhanden ist und ihn dann aktulisiere bzw. neu einfüge ist
> das Script iree langsam!
> Würde ich die DB mit TRUNCATE leeren und das file einfach jedesmal
> komplett in die DB schreiben wäre ich um längen schneller als mit der
> UPDATE/INSERT variante!
[...]
Was für eine Datenbank ist es denn? Ich gehe einfach mal von MySQL aus;
dann gibt es, wenn du Schnelligkeit wilst, LOAD DATA INFILE (bzw
mysqlimport auf der Kommandozeile). Weiterhin machen Indice
INSERT/UPDATE langsamer; disable keys / enable keys kann hier helfen.
Das hat aber eigentlich wenig mit PHP zu tun und viel mit der
verwendeten Datenbank.
KP
Prepared Statements wären ein Ansatz, der viel Performance raus holen
sollte, falls diese nicht schon verwendest.
--
Mit freundlichen Grüßen,
Christoph Herrmann
> Mein Script sieht im moment etwa so aus:
>
> while($data as $line){
> $result = $db->query("SELECT * FROM dst WHERE id = $line['id']
> if($db->rows($result) == 0){
> INSERT
> } else{
> UPDATE
> }
> }
> Es geht hier um > 300.000 einträge und mit jedem Update werden es mehr
> einträge! Gibt es nicht eine andere lösung, die Perfomanter ist?
Lass das SELECT sein. Feuer einfach das INSERT-Statement gegen die
Datenbank und wenn du eine Unique-Constraint-Violation bekommst machst
du ein UPDATE. Jenachdem welche Fall öfters vorkommt kannst du die
Statements auch tauschen.
Pseudocode:
try {
$db->insert(...);
} catch(UniqueConstraintViolation $ucv) {
$db->update(...);
}
Wenn du MySQL nutzt kannst du das wie Claus bereits schrieb kombinieren,
indem du die INSERT INTO ... ON DUPLICATE KEY UPDATE ... Syntax nutzt.
Würde nicht auch ein REPLACE den gleichen effekt haben?
Nicht ganz. INSERT ... ON DUPLICATE KEY UPDATE ändert bei vorhandenen
Datensätzen nur die Daten, die geändert werden sollen. REPLACE hingegen
löscht den alten Datensatz komplett und fügt einen neuen ein.
Gruß. Claus
Wieder was dazu gelernt. Danke.