[odb-users] 2.4.0: Object loading views with std::map container

Boris Kolpackov boris at codesynthesis.com
Tue Feb 17 10:35:36 EST 2015


Hi Quentin,

Quentin Deldycke <quentindeldycke at gmail.com> writes:

> I don't understand how to create the view for an object having a map on it.
> I have a structure like this:
> 
> class B
> {
> int x;
> int y;
> int z;
> }
> 
> class A
> {
> int a;
> int b;
> int c;
> std::map<int, B> example;
> }

What's the purpose of the view you are trying to create? If it is
to efficiently loading an object with a map (or any other container),
then there is not much you can do. Containers are "heavy".

If you try to load it with a single SELECT statement, then, for each
A object, you will get a row for each B object that it contains in
a map. All the A data will be simply duplicated. Probably not very
efficient.

If you don't do it with a single SELECT, then you will have to execute
a separate SELECT for the container and then one to load each B object
that it points to.

I think the most efficient way to load a large number of A objects
will be as follows:

1. First load all the B objects that the A objects will point to into
   the cache.

2. Then load all the A objects you are interested in.

So, something like this:

#pragma db view object(B) object(A inner) query(distinct)
struct B_for_A
{
  shared_ptr<B> b;
};

session s;
for (auto& b: db.query<B_for_A> (odb::query<B_for_A>::A::a < 10))
  ; // All we need is to get B's into the cache.

for (auto& a: db.query<A> (odb::query<A>::a < 10))
{
  // All the B's come from the cache.
}


> By the way, using this feature, to dump (threw network) the database, we
> manage to be 300% faster. And i think we can reach even more increase
> because there is still 2 queries for ~10 B class for each A class which are
> run at each iteration.

That's an impressive speedup. Let me know how the above approach compares
to a straight load, I am very interested.

Boris



More information about the odb-users mailing list