slow db4o querys on Android
Currently I am trying to integrate db4o into my App. I have a Model which contains - lets say 15 primitives - wrapped in other Objects. storing them is easy and fast, but to recieve them is pain. I tried NativeQuerys and SODA without any big difference. To give some of them an Index slows the query even more down.
in Example: I have a query looking like this:
public List<DatabaseReport> getCurrentDeviationReportsOnly(){
final long now = System.currentTimeMillis();
return getDatabase().query(new Predicate<DatabaseReport>() {
@Override
public boolean match(DatabaseReport candidate) {
return candidate.getReport().getBegin().getMillis() < now
&& candidate.getReport().getEnd().getMillis() > now;
}
}, mTimeComparator);
mTimeComparator is implemented as following:
public static class DatabaseScheduleReportTimeComparator implements Comparator<DatabaseReport>{
@Override
public int compare(DatabaseReport object1,
DatabaseReport object2) {
long first = object1.getReport().getBegin().getMillis();
long second = object2.getReport().getBegin().getMillis();
if (first < second) return 1;
if (first > second) return -1;
else {
first = object1.getReport().getEnd().getMillis();
second = object2.getReport().getEnd().getMillis();
if (first > second) return 1;
开发者_如何学编程if (first < second) return -1;
else return 0;
}
so with the Query above I expect to recievce like 40 of 100 Reports stored. I measured time for query and activation, and its about 3,5 SECONDS!!! For me, this seems VERY slow!
I played around a little and removed the Comparator in my query. Now I have an execution-time of about 1,2 Seconds. If I sort them manually with Collections.sort(myInstantiatedDatabaseReportList, mTimeComparator)
it executes in 47 Millis!! Am I doing something wrong? What is the reason that db4o likes to take more than 10 times more time than Collections.sort()?
What is the best way to optimize my model for db4o? (Activatable is not usefull in this case because the ResultingList will be passed in an ListAdapter, which needs every single member.)
Edit: due to the Answer below, I insert my SodaQuery here, too:
public List<DatabaseReport> getCurrentDeviationReports(){
final Date now = new Date(System.currentTimeMillis());
Query query = getDatabase().query();
query.constrain(DatabaseReport.class);
query.descend("mReport").descend("begin").descend("datetime").constrain(now).smaller();
query.descend("mReport").descend("end").descend("datetime").constrain(now).greater();
query.descend("mReport").descend("begin").descend("datetime").orderAscending();
query.descend("mReport").descend("end").descend("datetime").orderDescending();
return query.execute();
}
so the "datetime" here is a java.util.date Object. As I wrote above, it seems to me that indexing makes it SLOWER!
There are multiple things which could go wrong. So here's my check-list.
- Make sure that every field along this navigation is indexed. The 'report', 'begin' field and the 'millis' field.
- Is any of these fields a interface or a generic type? Then db4o won't use a index. You need concrete types so that db4o can find out what type the field is and use the indexes.
- When you're using native queries on Android, not that then you need to optimize these at built time. The reason is that the query optimizer cannot deal with
- Whats the type returned by getBegin()? If its a regular Java date, then the native optimizer doesn't do greater / smaller than comparisons. That only works with SODA
- The query returns 40 of 100 object? Then the sorting shouldn't be a big issue.
- SODA is also slow? That a little strange. Can you show me your SODA query?
精彩评论