Re: [Modeling-users] Problem with modeling efficency
Status: Abandoned
Brought to you by:
sbigaret
From: Sebastien B. <sbi...@us...> - 2003-11-27 10:43:32
|
Hi, <luk...@po...> wrote: > I have some questions about modeling efficency. Lets consider the followi= ng > example: >=20 > Model: > (mother lives in one province, in one province lives many mothers) > [ snipped model: Mother <<------> Province ] > > and python code (my orginal code translated from Polish to English:-): >=20 > EC=3DEditingContext() > mothers=3DEC.fetch('Mothers') > for mother in mothers: > id=3Dmother.getMothersId() > date=3Dmother.getBirthDate() >=20 > # efficency problematic code > province=3Dmother.gettoProvince().getName() >=20 > According to the manual everything is all right, and so it works. But... = in > database there is over 100 records. When I'm fetching the hole databse and > get only Id and BirthDate it takes 0.0 seconds - good. But when I try to = get > the name of the province by toProvince realtion it takes about 0,5 sec for > each row! So presenting this small database takes about minute. >=20 > 1. Am I doing something wrong or this slow working is the feature of > Modeling Framework? You're not doing anything wrong. What happens here is that the province is lazily fetched when needed, meaning that each iteration triggers a fetch when the line=20 > province=3Dmother.gettoProvince().getName() is hit. You can verify this by activating the mdl db-log (env. variable MDL_ENABLE_DATABASE_LOGGING). > 2. Is there any explanation for this or another way to get this data but > much faster? There are two ways of making this faster: 1. by default the framework opens a connection to the db, fetches, then closes the connection; if you do not want that, set the env. variable=20 MDL_PERMANENT_DB_CONNECTION to "1" (see details at http://modeling.sf.net/UserGuide/env-vars-core.html). NB: the reason for this default behaviour originally was that there were problems with psycopg in a MT environment and that seemed to solve this --but the problem is now solved and there is no reason for this to remain the default, we should probably change that. 2. Doing this, the fetch will probably be significantly faster, however you still get one fetch per ietration, which is not that efficient since you know that you'll need all of them anyway, so you probably want to fetch them all. We've discussed this some time ago with Yannick (see https://sf.net/mailarchive/forum.php?thread_id=3D2766300&forum_id=3D10674) and at that time I made a patch for DBContext working w/ to-many relationships only. Since in your case you deal w/ to-one relationships I've updated the patch: https://sf.net/tracker/index.php?func=3Ddetail&aid=3D771009&group_id=3D5893= 5&atid=3D489337 so you can use it w/ to-one relationship as well. Then you can try it like that: ------------------------------------------------------------------------ def databaseContext(entityName, ec): from Modeling.FetchSpecification import FetchSpecification fs=3DFetchSpecification(entityName) return ec.rootObjectStore().objectStoreForFetchSpecification(fs) =20=20 from Modeling.ModelSet import defaultModelSet dbContext=3DdatabaseContext('Company', ec) rel=3DdefaultModelSet().entityNamed('Mothers').relationshipNamed('toProvi= nce') EC=3DEditingContext() mothers=3DEC.fetch('Mothers') =20=20 # Now fetch all provinces of mothers in a single fetch dbContext.batchFetchRelationship(rel, mothers, ec) =20=20 for mother in mothers: id=3Dmother.getMothersId() date=3Dmother.getBirthDate() =20=20 province=3Dmother.gettoProvince().getName() ------------------------------------------------------------------------ This makes the whole fetch even faster (because all the fetching is done in a single roundtrip to the db). BTW is there anyone here still using the original patch for toMany relationships? (Yannick?) I should probably add this feature to the framework, it's been regularly asked. Do we want this in the next release? -- S=E9bastien. PS: as I said it previously when I sent the first version of the patch, this is not the definitive user-friendly interface ;) There will probably be a more convenient method at the EditingContext level, something like ec.batchFetch(mothers, 'toProvince') e.g. |