effectieve update query
Nieuw op het forum maar niet nieuw met php. Althans het is alweer een tijd geleden dus wel wat roestig. Maar ik heb besloten om mij er 100% in te verdiepen maar daarvoor heb ik zo nu en dan wat hulp nodig.
Zo genoeg voorstelrondje ik begin meteen met een vraag. Dit is een vraag die mij overigens al lang bezig houdt maar nu pas echt nodig is om uit te zoeken.
Ik heb een tekst bestand die we krijgen van een leverancier. Deze lees ik uit en maak er een array van. Die array wordt gebruikt in een update query om de voorraad te update in een mysql database (die, je raadt het al, achter een website hangt)
Quote:
"UPDATE ".$db.".products SET voorraad=".$voorraad." WHERE voorraad < ".$voorraad." AND barcode=".$parts[0]."";
Nu is die array vrij groot en duurt dit script zo lang dat de server hem afkapt. Nu kan ik mij niet voorstellen dat dit normaal is...
Hoe verwerk ik deze query op een correcte manier zodat de server er niet bijna in stikt?
Alvast bedankt voor de hulp :-)
Je kan je file lezen per record en dat dan meteen in de database te trappen ipv eerst in een array
maar dan voert hij toch evengoed elke regel appart uit? Dat lijkt mij juist niet de bedoeling namelijk... Mits ik je niet helemaal goed volg?
Michael schouman op 18/02/2011 11:01:17:
maar dan voert hij toch evengoed elke regel appart uit? Dat lijkt mij juist niet de bedoeling namelijk... Mits ik je niet helemaal goed volg?
Nou als je 10000 dingen in een array rost is het niet de query waar php om zeurt maar om de array.
10000 keer een query rossen hoor je niemand klagen als er goeie indexen op je velden liggen (bvb een unique index op je barcode)
Ik neem aan dit dit niet elke minuut gebeurd maar 1 keer per dag
Toevoeging op 18/02/2011 11:09:02:
Als je de tabel steeds moet updaten zou ik er een InnoDB tabel van maken
Gewijzigd op 18/02/2011 11:04:54 door Jelle -
Die unique index staat niet op het barcode veld helaas.
Dus ik ben bang dat het toch anders moet.
Ik zat zelf te denken aan het volgende:
Eerst een select op de regels die dus echt voldoen aan het statement en dan pas een update. Dat zou het aantal regels toch wel moeten halveren.
Hoe klinkt dat?
Dan kan je een unique key creeren door dit uit te voeren
Hoeveel records heeft je tabel?
Maar, voor de beeldvorming, in hoeverre is dit echt nodig? Wat gebeurt er precies als ik jou advies opvolg?
Michael schouman op 18/02/2011 11:22:23:
de tabel products heeft 18,708 rows. Het barcode veld is in die zin wel unique ja.
Maar, voor de beeldvorming, in hoeverre is dit echt nodig? Wat gebeurt er precies als ik jou advies opvolg?
Maar, voor de beeldvorming, in hoeverre is dit echt nodig? Wat gebeurt er precies als ik jou advies opvolg?
Nou als je het veld een unique id geeft hoeft je query alleen de index te volgen en dat duurt ongeveer 0.0006 seconde.
Als je er geen unique id op zet dan moet je query de hele tabel scannen om elk record te gaan vergelijken of het veld jouw barcode is en dat kan wel even duren.
Zeg jij moet 18,708 updates doen en je tabel heeft 18,708 records.
Dan onderzoekt de tabel met unique key 18,708 in totaal
En zonder unique key 349989264
Toevoeging op 18/02/2011 11:32:38:
In ieder geval: Je unique key zorgt ervoor dat je query snel gaat (zoals je wou in je openings post)
En verders om je script ook sneller te laten gaan moet je de query per record dat je uitleest uitvoeren en niet alle 19000 eerst opslaan in een array
Gewijzigd op 18/02/2011 11:32:48 door Jelle -
Als je met id bedoeld gewoon dat elke row een id heeft dan is dat wel al zo, elk product heeft een unique id... Dat spreekt voor zich haha.
Maar dan zou ik een select moeten doen op de barcode (aangezien dat het enige is wat overeenkomt tussen file en database) om vervolgens de id te gebruiken in een update statement?
Edit:
$idq = "SELECT `id` from ".$db.".products WHERE voorraad<".$voorraad." AND barcode=".$parts[0]."";
$result = mysql_query($idq);
while ($row = mysql_fetch_array($result)) {
echo "Kleiner dan:";
echo $row["id"]. "<br />";
}
$uq = "UPDATE ".$db.".products SET voorraad=".$voorraad." WHERE ".$row[id]."";
Zoiets?
$idq = "SELECT `id` from ".$db.".products WHERE voorraad<".$voorraad." AND barcode=".$parts[0]."";
$result = mysql_query($idq);
while ($row = mysql_fetch_array($result)) {
echo "Kleiner dan:";
echo $row["id"]. "<br />";
}
$uq = "UPDATE ".$db.".products SET voorraad=".$voorraad." WHERE ".$row[id]."";
Zoiets?
Gewijzigd op 18/02/2011 11:45:07 door michael schouman
Je barcode is je relatie tussen de file en je database. Je moet dus zorgen dat je barcode een goeie index heeft. Aangezien je barcode in je database unique is kan je daar een unique key op leggen (zie vorige posts)
Als je nu een update of select doet met barcode = 'iets' dan kan mysql snel vinden wat je bedoeld aangezien het een goeie index heeft op barcode (een unique key is een index)
Dus je query in je openings post zal doordoor een snelle query worden en kan je behouden
En ik zit even te kijken in phpmyadmin om toch even te controleren of er geen index bij staat.
screenshotje:
Ik weet niet of dat nou goed is of niet eigenlijk
Gewijzigd op 18/02/2011 13:30:44 door michael schouman
Michael schouman op 18/02/2011 13:26:45:
ow shit ik zie net dat er ook lege velden zitten in 'barcode' maakt dat uit?
Ja dat maakt uit dan kan je geen unique index erop zetten. Je kan er wel een gewone index opzetten (kan gewoon via phpmyadmin) en dat zou je query ook versnellen.
Je hebt overgens wel veel indexes
Gewijzigd op 18/02/2011 13:56:38 door Jelle -
Maar nu gaat dat hele feest eigenlijk niet door en ben ik terug bij af?
Michael schouman op 18/02/2011 14:59:05:
Maar nu gaat dat hele feest eigenlijk niet door en ben ik terug bij af?
Nee je hoeft alleen een index op barcode te leggen en je hebt hetzelfde effect als unique (alleen unique geeft net iets minder overhead maar dat kan niet op je column wat die is dus niet unique vanwege de empty values die je hebt)
Dus gooi een index op barcode en je script is sneller
Gewijzigd op 18/02/2011 15:41:23 door Jelle -
Edit:
Ok maar hij heeft het wel gedaan zonder errors :-)
Ok maar hij heeft het wel gedaan zonder errors :-)
Gewijzigd op 18/02/2011 16:37:05 door michael schouman