Datenabgleich dBase -> SQL dauert 4 Stunden?!
Armin
- php
Hi zusammen,
ich hab ein Problem mit einem PHP-Script das einen täglichen Datenabgleich eines Artikelstammes vornehmen soll.
Das Script ladet vom Server eines Lieferanten ein .zip-File runter, entpackt dieses. So entstehet ein dBase-File das meine mySQL-DB auf den aktuellen Stand bringen soll.
Dazu verwende ich zuerst ein Select um heraus zu finden ob der Datensatz bereits existiert. Wenn ja, wird er mit einem Update aktualisiert, wenn nein wird er mit einem Insert angelegt.
---------------------------------------------------------------
echo "-> READ DBASE-FILE " . $EXTFILE . "...\n";
if(!$dbh = dbase_open($EXTFILE, 0))
{
echo "<- CAN'T OPEN DBASE-FILE " . $EXTFILE . "\n\n";
}
else
{
$num_fields = dbase_numfields ($dbh);
$num_rows = dbase_numrecords($dbh);
echo "<- READING DBASE FILE WITH " . $num_fields . " FIELDS IN " . $num_rows . " ROWS...\n";
$i = 1;
$isi = 0;
$isu = 0;
while($i <= $num_rows)
{
$rr = dbase_get_record_with_names($dbh, $i);
// hier werden die variabeln dann noch gesetzt.
$sql = "SELECT products\_id
FROM " . $ASE\_DBTABL\_PROD . "
WHERE products\_dist
LIKE '" . $DIST . "' AND products\_anr
LIKE '" . $DIST . $products_anr . "' LIMIT 0 , 1";
$result = mysql_query($sql, $ASE_DBCONN1);
if(mysql_num_rows($result) > 0)
{
$sql = "UPDATE " . $ASE\_DBTABL\_PROD . "
SET ";
$sql .= " products\_hnr
= '" . $products_hnr . "', products\_mfg
= '" . $products_mfg . "', products\_grp1
= '" . $products_grp1 . "', products\_grp2
= '" . $products_grp2 . "', products\_grp3
= '" . $products_grp3 . "', products\_dsc1
= '" . $products_dsc1 . "', products\_dsc2
= '" . $products_dsc2 . "', products\_war
= '" . $products_war . "', products\_pprc
= '" . $products_pprc . "', products\_sprcn
= '" . $products_sprcn . "', products\_sprcb
= '" . $products_sprcb . "', products\_tax
= '" . $products_tax . "', products\_dat1
= '" . $products_dat1 . "', products\_aprc
= '" . $products_aprc . "', products\_adat
= '" . $products_adat . "', products\_pdf
= '" . $products_pdf . "', products\_img
= '" . $products_img . "', products\_wght
= '" . $products_wght . "', products\_ean
= '" . $products_ean . "', products\_lst
= NOW() ";
$sql .= " WHERE products\_dist
LIKE '" . $DIST . "' AND products\_anr
LIKE '" . $DIST . $products_anr . "'";
$isu++;
}
else
{
$sql = "INSERT INTO " . $ASE\_DBTABL\_PROD . "
(products\_dist
, products\_anr
, products\_hnr
, products\_mfg
, products\_grp1
, products\_grp2
, products\_grp3
, products\_dsc1
, products\_dsc2
, products\_war
, products\_pprc
, products\_sprcn
, products\_sprcb
, products\_tax
, products\_stor
, products\_dat1
, products\_dat2
, products\_aprc
, products\_adat
, products\_pdf
, products\_img
, products\_wght
, products\_ean
, products\_crt
, products\_lst
)";
$sql .= "VALUES ('" . $DIST . "', '" . $DIST . $products_anr . "', '" . $products_hnr . "', '" . $products_mfg . "', '" . $products_grp1 . "', '" . $products_grp2 . "', '" . $products_grp3 . "', '" . $products_dsc1 . "', '" . $products_dsc2 . "', '" . $products_war . "', '" . $products_pprc . "', '" . $products_sprcn . "', '" . $products_sprcb . "', '" . $products_tax . "', '" . $products_stor . "', '" . $products_dat1 . "', '" . $products_dat2 . "', '" . $products_aprc . "', '" . $products_adat . "', '" . $products_pdf . "', '" . $products_img . "', '" . $products_wght . "', '" . $products_ean . "', '" . $products_crt . "', NOW())";
$isi++;
}
$result = mysql_query($sql, $ASE_DBCONN1);
$i++;
}
}
---------------------------------------------------------------
Das funktioniet soweit auch, leider dauert es viel zu lange. Auf einem Athlon64 3,0 mit 1 GB Ram kann das schon 30-40 Minuten dauern. Auf dem Webserver, der längsamer ist und den ich mit mit anderen Sites teilen muss hab ich teilweise 2-3 Stunden gebraucht, und dabei den Server komplett ausgelastet.
Hat wer eine Idee, wie man das ganz optimieren kann? Das Problem scheint eindeutig am SQL-Server zu liegen und nicht an PHP. Soweit mir aufgefallen ist, scheint das Problem beim Select oder Update zu liegen, denn wenn ich die DB einfach vorher leere und alles Inserte gehts entschieden schneller.
Bin für jeden Tipp dankbar,
Armin
Hallo Armin,
Hat wer eine Idee, wie man das ganz optimieren kann? Das Problem scheint eindeutig am SQL-Server zu liegen und nicht an PHP. Soweit mir aufgefallen ist, scheint das Problem beim Select oder Update zu liegen, denn wenn ich die DB einfach vorher leere und alles Inserte gehts entschieden schneller.
Update und Select können natürlich recht lange dauern, besonders, wenn es um große Tabellen geht. Das ist so ohne genaue Angabe schwer abschätzbar.
Hast du schon daran einen Index oder auch mehrere zu setzen auf diejenigen Spalten, die nicht Schlüsselspalten sind, aber in den "WHERE"-Klauseln vorkommen? Wenn diese Spalteninhalte eine hohe Granularität aufweisen, wirkt das oft Wunder.
Gruß Mia
Hi,
$sql = "SELECT
products\_id
FROM" . $ASE\_DBTABL\_PROD . "
WHEREproducts\_dist
LIKE '" . $DIST . "' ANDproducts\_anr
LIKE '" . $DIST . $products_anr . "' LIMIT 0 , 1";
Brauchst Du wirklich LIKE? Oder würde es = auch tun?
Du erwartest ja offensichtlich nur ein einziges Ergebnis (LIMIT 0,1) ...
Außerdem schreibst Du die Werte später direkt so in die Datenbank - die Abfrage auf Ähnlichkeit (LIKE) ist also wohl eher sinnlos.
Sind die Spalten products_dist und products_anr indiziert?
$sql = "UPDATE
" . $ASE\_DBTABL\_PROD . "
SET ";
[...]
$sql .= " WHERE
products\_dist
LIKE '" . $DIST . "' ANDproducts\_anr
LIKE '" . $DIST . $products_anr . "'";
Hier fragst Du wieder über products_dist und products_anr ab - Du hattest vorher aber schon die (vermutlich eindeutige, weil autoincrement und Primary Key?) id ermittelt - es bietet sich hier also an, die id wiederzuverwenden.
cu,
Andreas
hi,
Hat wer eine Idee, wie man das ganz optimieren kann? Das Problem scheint eindeutig am SQL-Server zu liegen und nicht an PHP. Soweit mir aufgefallen ist, scheint das Problem beim Select oder Update zu liegen, denn wenn ich die DB einfach vorher leere und alles Inserte gehts entschieden schneller.
kannst du REPLACE verwenden anstatt dich vom SELECT abhängig für UPDATE oder INSERT zu entscheiden ...?
gruß,
wahsaga