[php/xml] Efficientie check, meerdere xml feeds naar mysql

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • xAndyx
  • Registratie: Maart 2004
  • Laatst online: 27-03 13:04
Om te voorkomen dat ik de server onnodig belast wil ik op een efficiente manier xml feeds naar de mysql database schrijven. Ook om geheugen problemen te voorkomen. Dit script zal uiteindelijk via een cronjob (dagelijks/uurlijks) lopen.

Volgens mij werkt het zo het beste;
- In een array heb ik de feed url's staan en deze feeds probeer ik zo klein mogelijk te houden. Bijv door niet alle producten in een grote feed in 1 keer op te halen, maar met een aparte categorie-feed.

- Met een foreach-loop ga ik door de feeds.

- Binnen de foreach-loop maak ik een object aan xmlFeed.

- Ik kopieer het xml bestand naar de server met bijv xmlFeed->DownloadXML.

- Ik verwerk het xml bestand lokaal met xmlFeed->VerwerkXML (evt met een property dat de xml structuur aangeeft). En met gebruik van simplexml_load_file(). Alle producten in het xml bestand ga ik toevoegen aan 1 grote query string en voer deze uit. Daarbij moet gekeken worden naar de titel van een product. Dus ik dacht aan een INSERT INTO producten (titel, prijs) VALUES (appelsap, 2) ON DUPLICATE KEY UPDATE prijs = (2). Dus als appelsap er al in staat alleen prijs aanpassen.
De reden om 1 grote query string te nemen is om niet duizenden insert queries te gaan doen ivm belasting op de server.

- Als de gegevens in de database zijn geschreven verwijder ik het lokale xml bestand (misschien overbodig). En gooi ik het object weg met object = null (misschien is er een betere manier?)

- De foreach-loop pakt de volgende en begint opnieuw (evt eerst statistieken in de db zetten oid).

Is dit de juiste manier van verwerken of zijn er nog dingen waar ik niet aan heb gedacht?

Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 20:18

MueR

Admin Tweakers Discord

is niet lief

Voor de performance zou je kunnen kijken naar prepared statements. Dat scheelt al een hoop omdat MySQL maar een keer de query hoeft te parsen. Verder zou je kunnen overwegen om de updates en dergelijke in PHP te schiften. Het ophalen van een set met producten reeds in je DB en die vergelijken kan ook tijd en load schelen, maar dat zou je moeten testen/benchmarken, dat weet ik zo niet uit het hoofd.

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

  • ZpAz
  • Registratie: September 2005
  • Laatst online: 23:16
Voor variabelen te 'verwijderen' is een speciale functie namelijk: unset.

Tweakers Time Machine Browser Extension | Chrome : Firefox


Acties:
  • 0 Henk 'm!

  • xAndyx
  • Registratie: Maart 2004
  • Laatst online: 27-03 13:04
prepared statements kunnen inderdaad handig zijn. Is het dan verstandig om losse kleine queries te gaan doen? Of blijft 1 grote querie per xml bestand slimmer?

Verder vroeg ik me af wat je bedoeld met Updates en dergelijke in php te schiften?

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:16

crisp

Devver

Pixelated

Probeer in de eerste plaats het ophalen en verwerken van een feed helemaal te skippen indien je weet dat een feed niet is veranderd. Dus: houd bij wanneer je de laatste keer een feed hebt opgehaald, en stuur op basis daarvan if-modified-since headers mee bij het opnieuw ophalen. Vang vervolgens 304 responses af.
Daarnaast zou je per feed ook een checksum bij kunnen houden en bij het opnieuw ophalen de checksum kunnen vergelijken.

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • xAndyx
  • Registratie: Maart 2004
  • Laatst online: 27-03 13:04
if-modified-since header gaat niet werken denk ik. Aangezien de feeds van een dynamische pagina opgehaald worden. Ik kan wel aan de leverancier vragen of ze een "laatste update" veld kunnen toevoegen.

Tot die tijd maar uurlijks/dagelijks de boel sowieso binnen halen..

Wat ik natuurlijk wel kan checken is filesize van het binnengehaalde xml bestand. Als dit meer of minder is moet ik gaan checken. Dat is misschien wel een idee.

[ Voor 23% gewijzigd door xAndyx op 12-12-2009 19:10 ]


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:16

crisp

Devver

Pixelated

Een checksum is natuurlijk betrouwbaarder; kijk bijvoorbeeld eens naar md5_file.

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
xAndyx schreef op zaterdag 12 december 2009 @ 17:44:
if-modified-since header gaat niet werken denk ik. Aangezien de feeds van een dynamische pagina opgehaald worden.
De meeste feeds zijn dynamisch. ;) Test gewoon eens of er support voor in zit.

{signature}


Acties:
  • 0 Henk 'm!

Verwijderd

Je huidige aanpak met simplexml_load_file() vereist dat je het volledige XML bestand in 1x in het geheugen laad. Dit schaalt niet echt als je bestanden groter worden. Als dit een probleem is dan zou ik eens naar http://php.net/manual/en/function.xml-parser-create.php kijken. Hierbij krijg je niet het gehele document als een boom terug, maar loop je tag voor tag door het document heen. Het is een enorme PITA om mee te werken, maar soms kan je niet anders.

Als je feeds per stuk vrij klein zijn, dan is dit niet de moeite waard.

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Overigens zijn de tot nu genoemde tweaks ook later door te voeren, en als je het een beetje netjes opzet wellicht nog eenvoudig ook. Je moet ook weer niet te lang over je theoretische bottlenecks praten. ;)

Na het bedenken van een opzet hoe het probleem aan te pakken/te verdelen, zou ik gewoon beginnen en daarbij eenvoudige tools (bv. simplexml) gebruiken. Dan kan je vervolgens met realistische (test)data gaan profilen en weet je waar je moet optimaliseren en of die optimalisaties er echt toe doen. :)

[/standaard_KISS_en_profile_praatje] :+

[ Voor 4% gewijzigd door Voutloos op 13-12-2009 11:24 ]

{signature}

Pagina: 1