Mapper: Is it possible to avoid the "n+1" selects?

29 views
Skip to first unread message

Jeppe Nejsum Madsen

unread,
Aug 13, 2009, 8:11:06 AM8/13/09
to lif...@googlegroups.com
Hi

I have a mapped object A with a foreign key to mapped object B.

I need to display the information (A+B) in a table. The not so smart way
is to first query on the As and then for each A, get the B. This
results in n+1 selects.

Is it possible to ask Mapper, when querying for the As, that it should
join with Bs table to fetch the B at the same time (ie the equivalent of
join fetching in Hibernate)?

/Jeppe



Derek Chen-Becker

unread,
Aug 13, 2009, 11:12:34 AM8/13/09
to lif...@googlegroups.com
You should be able to use the PreCache QueryParam to tell Mapper to pre-fetch the mapped object:

http://scala-tools.org/scaladocs/liftweb/1.0/net/liftweb/mapper/PreCache.html

Derek

Jeppe Nejsum Madsen

unread,
Aug 13, 2009, 11:44:49 AM8/13/09
to lif...@googlegroups.com
Derek Chen-Becker <dchen...@gmail.com> writes:

> You should be able to use the PreCache QueryParam to tell Mapper to
> pre-fetch the mapped object:
>
> http://scala-tools.org/scaladocs/liftweb/1.0/net/liftweb/mapper/PreCache.html

Ahh nice. I missed that one, Thanks

/Jeppe

Jeppe Nejsum Madsen

unread,
Aug 18, 2009, 3:32:48 AM8/18/09
to lif...@googlegroups.com
On Thu, Aug 13, 2009 at 5:12 PM, Derek Chen-Becker<dchen...@gmail.com> wrote:
> You should be able to use the PreCache QueryParam to tell Mapper to
> pre-fetch the mapped object:
>
> http://scala-tools.org/scaladocs/liftweb/1.0/net/liftweb/mapper/PreCache.html

Ok, time for a bonus question: Can this be extended to more than 1 level?

I have something similar to the following

class Vehicle extends LongKeyedMapper[Vehicle] with IdPK {
object vehicleType extends MappedLongForeignKey(this, VehicleType)
}

class VehicleType extends LongKeyedMapper[VehicleType] with IdPK {
object brand extends MappedLongForeignKey(this, Brand)
}

class Brand extends LongKeyedMapper[Brand] with IdPK {
}

When displaying the list of vehicles I need to show both the vehicle,
the vehicleType & the brand in the same table

So to get the list of vehicles and caching the vehicletypes I do this:

override def findForListParams: List[QueryParam[Vehicle]] =
List(By(account, User.currentUser.open_!.account.is),
PreCache(vehicleType))

But I still get the n+1 selects when trying to resolve
vehicleType.brand. Can this be remedied somehow?

/Jeppe

Derek Chen-Becker

unread,
Aug 18, 2009, 1:41:22 PM8/18/09
to lif...@googlegroups.com
I don't think it currently supports it, but I'd have to look at the source to give a definitive answer.

David Pollak

unread,
Aug 18, 2009, 1:46:23 PM8/18/09
to lif...@googlegroups.com
On Tue, Aug 18, 2009 at 12:32 AM, Jeppe Nejsum Madsen <je...@ingolfs.dk> wrote:

On Thu, Aug 13, 2009 at 5:12 PM, Derek Chen-Becker<dchen...@gmail.com> wrote:
> You should be able to use the PreCache QueryParam to tell Mapper to
> pre-fetch the mapped object:
>
> http://scala-tools.org/scaladocs/liftweb/1.0/net/liftweb/mapper/PreCache.html

Ok, time for a bonus question: Can this be extended to more than 1 level?

You'd have to try it.  ;-)

I don't think Mapper officially supports multiple levels of precaching.
 


I have something similar to the following

class Vehicle extends LongKeyedMapper[Vehicle] with IdPK {
 object vehicleType extends MappedLongForeignKey(this, VehicleType)
}

class VehicleType extends LongKeyedMapper[VehicleType] with IdPK {
 object brand extends MappedLongForeignKey(this, Brand)
}

class Brand extends LongKeyedMapper[Brand] with IdPK {
}

When displaying the list of vehicles I need to show both the vehicle,
the vehicleType & the brand in the same table

So to get the list of vehicles and caching the vehicletypes I do this:

 override def findForListParams: List[QueryParam[Vehicle]] =
     List(By(account, User.currentUser.open_!.account.is),
PreCache(vehicleType))

But I still get the n+1 selects when trying to resolve
vehicleType.brand. Can this be remedied somehow?

/Jeppe





--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp

Jeppe Nejsum Madsen

unread,
Aug 18, 2009, 4:31:34 PM8/18/09
to lif...@googlegroups.com
On Tue, Aug 18, 2009 at 7:46 PM, David
Pollak<feeder.of...@gmail.com> wrote:
>
>
> On Tue, Aug 18, 2009 at 12:32 AM, Jeppe Nejsum Madsen <je...@ingolfs.dk>
> wrote:
>>
>> On Thu, Aug 13, 2009 at 5:12 PM, Derek Chen-Becker<dchen...@gmail.com>
>> wrote:
>> > You should be able to use the PreCache QueryParam to tell Mapper to
>> > pre-fetch the mapped object:
>> >
>> >
>> > http://scala-tools.org/scaladocs/liftweb/1.0/net/liftweb/mapper/PreCache.html
>>
>> Ok, time for a bonus question: Can this be extended to more than 1 level?
>
> You'd have to try it.  ;-)

Believe me, I tried :-) Couldn't really figure out what to use as
parameter and looking at dealWithPrecache it seems like the two tables
need to be directly linked

It's not super critial atm, so I'll get back to this if necessary

/Jeppe

Long Hoàng Đình

unread,
Mar 21, 2015, 11:20:03 PM3/21/15
to lif...@googlegroups.com
Hi everyone!

I'm looking for solutions to tune up Lift application. And the only solution for N+1 problem that I can find is here.
Since the topic is quite old (2009), I just want to ask are there any updates on this?
Reply all
Reply to author
Forward
0 new messages