Search code examples
c#.netdb4o

How to efficiently retrieve every Nth object from DB4O ordered on an indexed field


I store a lot of events in a DB4O db. The events are timestamped and I've indexed the field. Retrieving (an enumerator of) all events, ordered by timestamp, takes almost no time at all (as they aren't activated). However, what if I only want to retireve every 10. I can loop, but then I'll have to do a count, which takes a significant time. Even returning FirstOrDefault() from the Enumerable (yes, I'm in C# and LINQ) takes time. If the field is indexed, shouldn't it be pretty easy to find the first one in an ordered set?

Yes, I don't have a lot of experience using DB4O, but the app I've written works well. Normally I push millions of events to the db and then retrieve a few based on a short timespan. No problem at all and the app performs very well. Response time for a typical query is less than 100 ms.

Now I want to retrieve a sample of all the events. Every ten, or so ... How do I accomplish that?


Solution

  • You are using LINQ right know? Are you sure that the query takes no time? Because LINQ queries are executed when you start iteration over it. Not before.

    Also note that db4o doesn't use the index for sorting right now. That means for huge result sets sorting will be slow.

    FirstOrDefault() already takes a lot of time? There can be two reasons. Either it takes time because the query is executed there. Or because db4o need time to activate the object. Is it a very complex object. My guess is that the query time could be the issue, because you said that the .Count() operation takes its time.

    Now you want to get only every 10th object. Well I believe that the .ElementAt() operator hasn't been yet implemented in an optimized form for db4o. That means it will activate every object in between. In the latest db4o release the .Skip() operated shouldn't activate every object in between. So you could skip to the right position an the use .FirstOrDefault() there.