[PHP5] O/R mapping vs performance

Pagina: 1
Acties:

  • cashewnut
  • Registratie: Januari 2002
  • Laatst online: 09-11-2025
Voor een afstudeeropdracht moet ik met een medestudent een webapplicatie ontwikkelen. Waarschijnlijk gaan we daarbij PHP5 gebruiken (bedrijf is ermee bekend etc.). We willen eigenlijk het liefst zoveel mogelijk object-georienteerd werken (maakt de boel een stuk simpeler), maar nu loop ik tegen een dilemma aan.

Zodra je een abstractielaag voor de database gaat maken, kun je je queries niet meer aanpassen op de situatie. Stel bijvoorbeeld dat je een tabel Klanten en een tabel Contracten hebt. je gaat naar de HTML pagina voor het weergeven van klantinformatie (inclusief contracten van die klant). Dan zou je normaal gesproken bvb een join uitvoeren waardoor je ineens alle gegevens krijgt die je nodig hebt. Maar als je op die manier de class Klant instantieert, heb je weer overhead zodra je bvb alleen de NAW-gegevens van de klant nodig hebt. Dus verlies je weer performance. Het alternatief is natuurlijk om een aparte query voor contracten te gebruiken, maar dan verlies je performance in het eerste geval (2 queries ipv 1).

Op mijn vorige stageplek waren mijn collega's nogal gebrand op performance, dus pastte ik geen OR mapping toe. Nu wil ik dat wel doen, maar verlies ik er niet teveel performance mee op deze manier?

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 22-03 18:12
Dat ligt er maar net aan wat voor OR mapping je toepast. Als je puur reflectie gebruikt dan kan het wel erg langzaam worden. Als je met behulp van XML meta data een mapping class genereert, dan kun je de code nog aanpassen en tweaken voor performance. Dat is ook gedeeltelijk de reden waarom ik het zo doe. Verder is het gewoon benchmarken als je twijfelt. Als het niet snel genoeg is ga je gewoon over op een andere techniek, naast verder OR mapping te gebruiken. Dat lijkt me niet zo'n probleem.

Noushka's Magnificent Dream | Unity


Verwijderd

Ik meen mij te herinneren dat er in Hibernate een functie zit om joins automatisch te laten genereren. Je kan dit dan in je mapping schema definieren (lazy load of niet) en automatisch worden dan alle contracten van je klant in één query mee opgehaald.

Dus moet een O/R mapper per definitie niet altijd traag zijn! Hij kan ook een beetje slim zijn als je er slim mee werkt

[ Voor 20% gewijzigd door Verwijderd op 07-03-2005 17:00 ]


  • MisterData
  • Registratie: September 2001
  • Laatst online: 10-05 19:07
Verwijderd schreef op maandag 07 maart 2005 @ 17:00:
Ik meen mij te herinneren dat er in Hibernate een functie zit om joins automatisch te laten genereren. Je kan dit dan in je mapping schema definieren (lazy load of niet) en automatisch worden dan alle contracten van je klant in één query mee opgehaald.

Dus moet een O/R mapper per definitie niet altijd traag zijn! Hij kan ook een beetje slim zijn als je er slim mee werkt
Daarnaast kan een O/R mapper als Hibernate heel goed cachen en als je bijvoorbeeld setName() op een gebruiker-entiteit aanroept dan weet Hibernate dat 'ie alleen dat veld hoeft aan te passen, waar je normaal gesproken een lange(re) query voor maakt :) Dus het kan ook sneller zijn...

  • EfBe
  • Registratie: Januari 2000
  • Niet online
MisterData schreef op maandag 07 maart 2005 @ 17:04:
Daarnaast kan een O/R mapper als Hibernate heel goed cachen
Cache is alleen sneller indien je versioning informatie opslaat bij de PK. Je kunt dan besparen op het ophalen van data. Immers, als jij 50 customer objects in je cache hebt staan en je start een willekeurige customer query, zul je altijd naar de database moeten. Je kunt dan, wanneer je versioning informatie opslaat, de PK en de version ophalen en die dan vergelijken met je cached versie, zodoende dus alleen die objects ophalen die niet in de cache staan of verouderd zijn. Hibernate slaat geen version nummer op per row. Dit resulteert dan in een tragere operatie, want je moet dan altijd fetchen EN na iedere fetch je cache updaten.
en als je bijvoorbeeld setName() op een gebruiker-entiteit aanroept dan weet Hibernate dat 'ie alleen dat veld hoeft aan te passen, waar je normaal gesproken een lange(re) query voor maakt :) Dus het kan ook sneller zijn...
nadeel alleen dat hibernate per field compares doet wanneer je een entity savet. Dit is op zich niet 1 2 3 traag, maar bij een paar honderd entities merk je het wel.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Verwijderd

Versioning info opslaan in je PK? Dan ben ik benieuwd naar hoe het datamodel eruit ziet...
M'n eerste reactie was 'you must be nuts' :+

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 22-03 18:12
Verwijderd schreef op maandag 07 maart 2005 @ 18:58:
Versioning info opslaan in je PK? Dan ben ik benieuwd naar hoe het datamodel eruit ziet...
M'n eerste reactie was 'you must be nuts' :+
code:
1
2
3
4
5
6
CREATE TABLE tabel
(
  id INT,
  version INT,
  PRIMARY KEY(id, version)
);

Dat kan toch goed?

[ Voor 5% gewijzigd door Michali op 07-03-2005 19:01 ]

Noushka's Magnificent Dream | Unity


  • whoami
  • Registratie: December 2000
  • Laatst online: 09:19
Hmmm..... Toch lijkt het me sterk; ik hou niet van veranderende PK - values; en wat doe je dan met je foreign keys ?

Je kan natuurlijk wel een extra veld opslaan per record (een GUID bv) die de versie bijhoudt, maar dan zou ik 'm zeer zeker geen onderdeel van m'n PK maken (in de DB).
Ik denk echter niet dat EfBe bedoelde om dat ook te doen (de versie-info onderdeel van de PK maken); hij zegt: naast de PK kan je dan ook de versie-info ophalen, en dat is iets wat je dan idd ook wel kan doen.
In plaats van enkel de PK's, haal je dus ook de 'guid-timestamp' op.

[ Voor 78% gewijzigd door whoami op 07-03-2005 20:00 ]

https://fgheysels.github.io/


  • MisterData
  • Registratie: September 2001
  • Laatst online: 10-05 19:07
EfBe schreef op maandag 07 maart 2005 @ 18:29:
[...]
nadeel alleen dat hibernate per field compares doet wanneer je een entity savet. Dit is op zich niet 1 2 3 traag, maar bij een paar honderd entities merk je het wel.
Volgens mij kan Hibernate ook met zogenaamde 'proxy classes' (ik geloof met cglib oid) velden van een object als 'dirty' aanmerken op het moment dat je setXXX() aanroept (en dan heb je dus geen compares meer) :)

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Verwijderd schreef op maandag 07 maart 2005 @ 18:58:
Versioning info opslaan in je PK? Dan ben ik benieuwd naar hoe het datamodel eruit ziet...
M'n eerste reactie was 'you must be nuts' :+
Nee tezamen met de PK :P. Dus je hebt een unique_identifier (PK) en een versioning field(long) bijvoorbeeld. Dit is veelal niet aanwezig in bestaande databases.

[ Voor 6% gewijzigd door EfBe op 07-03-2005 20:45 ]

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • Skaah
  • Registratie: Juni 2001
  • Niet online
propel is een PHP5 O/R mapper, hij zag er wel goed uit.

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
Skaah schreef op maandag 07 maart 2005 @ 21:12:
propel is een PHP5 O/R mapper, hij zag er wel goed uit.
[url=http://http://propel.phpdb.org/]propel[/url] is idd een prima PHP5 O/R mapper (met een overigens prima werkende PHP4 backport van de runtime classes). Ik gebruik het sinds een tijdje met tevredenheid. ik geef niet zoveel om performance, maar snel is het inderdaad niet :).

Propel ondersteunt geen caching van geladen objecten zoals z'n neefje Torque. Maar dat zou je zelf erbij kunnen bouwen.

Maar het dynamisch genereren van efficiente queries mbv Criteria is geen probleem. Desnoods kun je altijd nog custom SQL queries toevoegen aan je om classes.

[ Voor 6% gewijzigd door Genoil op 07-03-2005 22:09 ]


  • cashewnut
  • Registratie: Januari 2002
  • Laatst online: 09-11-2025
Ik heb op phpPatterns ook een mogelijke oplossing gevonden: het Data Access Object Pattern. Daar stellen ze voor om elke query die 'normaal' gesproken in de logica zit, in implementaties van het Data Access Object (DAO) te stoppen. Het is dus niet zo 'mooi' als een echte OO representatie van de database, maar je centraliseert wel je queries en maakt onderscheid tussen data-access en logica.

Ik vind het wel vreemd dat ze de resultsets rechtstreeks gebruiken, ipv de gegevens in 2D arrays te zetten. Resultsets zijn IMO minder flexibel (je kunt er maar 1 keer doorheen lopen), dus ik denk dat ik dat anders ga doen.

Verwijderd

Je kunt meerdere keeren door een mysql resultset lopen: http://nl3.php.net/manual/en/function.mysql-data-seek.php

  • cashewnut
  • Registratie: Januari 2002
  • Laatst online: 09-11-2025
Je hebt gelijk. Ook voor PostgreSQL (wat wij gebruiken) kan dit, maar is het niet slechter voor de performance?
Pagina: 1