[odb-users] Question about query caching

Boris Kolpackov boris at codesynthesis.com
Tue Oct 2 03:44:43 EDT 2012


Hi Sean,

Stroud, Sean T <ststrou at sandia.gov> writes:

> I am new to ODB and have a question about query caching. I created
> the following data classes:
> 
> Sensor_Product
> Product_Header
> Ephemeris
> 
> The Sensor_Product has the following data members:
> -       Product_Header *m_header_ptr;
> -       Ephemeris *m_ephemeris_ptr;
> -       int m_id;  // the primary key
> 
> [...] 
> 
>       // Cache the results
>       sp_result.cache();

You don't really need to make this call since query results are
cached by default. You will need to explicitly pass false as a
second argument to database::query() in order to create an un-
cached result.


> What I am seeing is that the "Issue the query" section above
> does a SELECT with two LEFT JOINs to get the Sensor_Product,
> Product_Header and Ephemeris classes.

This is not quite correct. The JOINs are there to allow you to
use referenced object's members in query conditions. The data
for the objects themselves is not retrieved by this query, as
is evident from the select-list of the query.


> But then it looks like the "Iterate over the results" section
> causes more SELECT statements to be issued. In particular, each
> time the "*iter" expression is executed in the for loop, ODB is
> issuing two queries: one to select the Product_Header and one to
> select the Ephemeris.

When the iterator is dereferenced (*iter), the actual object
(Sensor_Product) is instantiated. Since it references two other
objects (Product_Header and Ephemeris), those have to be loaded
as well. The two SELECT statements that you see achieve exactly
that.


> This surprised me since I thought I was caching the results with
> the "sp_result.cache()" statement.

This has really nothing to do with caching. Quoting the manual
(Section 4.4, "Query Result"):

"If the result is cached, the database state of all the returned objects is
 stored in the application's memory. Note that the actual objects are still
 only instantiated on demand during result iteration. It is the raw database
 state that is cached in memory. In contrast, for uncached results the
 object's state is sent by the database system one object at a time as the
 iteration progresses."


> These extra select statements appear to slow things down considerably,
> so I'd like to understand why they are necessary and (more importantly)
> if there is a way I can eliminate them.

Yes, you can use lazy pointers to control if and when referenced objects
are loaded. Refer to Section 6.4, "Lazy Pointers" in the ODB manual for
details.

Boris



More information about the odb-users mailing list