tags:

views:

2335

answers:

4
+21  Q: 

db4o experiences?

I'm currently trying out db4o (the java version) and I pretty much like what I see. But I cannot help wondering how it does perform in a real live (web-)environment. Does anyone have any experiences (good or bad) to share about running db4o?

+31  A: 

We run DB40 .NET version in a large client/server project.

Our experiences is that you can potentially get much better performance than typical relational databases.

However, you really have to tweak your objects to get this kind of performance. For example, if you've got a list containing a lot of objects, DB4O activation of these lists is slow. There are a number of ways to get around this problem, for example, by inverting the relationship.

Another pain is activation. When you retrieve or delete an object from DB4O, by default it will activate the whole object tree. For example, loading a Foo will load Foo.Bar.Baz.Bat, etc until there's nothing left to load. While this is nice from a programming standpoint, performance will slow down the more nesting in your objects. To improve performance, you can tell DB4O how many levels deep to activate. This is time-consuming to do if you've got a lot of objects.

Another area of pain was text searching. DB4O's text searching is far, far slower than SQL full text indexing. (They'll tell you this outright on their site.) The good news is, it's easy to setup a text searching engine on top of DB4O. On our project, we've hooked up Lucene.NET to index the text fields we want.

Some APIs don't seem to work, such as the GetField APIs useful in applying database upgrades. (For example, you've renamed a property and you want to upgrade your existing objects in the database, you need to use these "reflection" APIs to find objects in the database. Other APIs, such as the [Index] attribute don't work in the stable 6.4 version, and you must instead specify indexes using the Configure().Index("someField"), which is not strongly typed.

We've witnessed performance degrade the larger your database. We have a 1GB database right now and things are still fast, but not nearly as fast as when we started with a tiny database.

We've found another issue where Db4O.GetByID will close the database if the ID doesn't exist anymore in the database.

We've found the Native Query syntax (the most natural, language-integrated syntax for queries) is far, far slower than the less-friendly SODA queries. So instead of typing:

// C# syntax for "Find all MyFoos with Bar == 23".
// (Note the Java syntax is more verbose using the Predicate class.)
IList<MyFoo> results = db4o.Query<MyFoo>(input => input.Bar == 23);

Instead of that nice query code, you have to an ugly SODA query which is string-based and not strongly-typed.

For .NET folks, they've recently introduced a LINQ-to-DB4O provider, which provides for the best syntax yet. However, it's yet to be seen whether performance will be up-to-par with the ugly SODA queries.

DB4O support has been decent: we've talked to them on the phone a number of times and have received helpful info. Their user forums are next to worthless, however, almost all questions go unanswered. Their JIRA bug tracker receives a lot of attention, so if you've got a nagging bug, file it on JIRA on it often will get fixed. (We've had 2 bugs that have been fixed, and another one that got patched in a half-assed way.)

If all this hasn't scared you off, let me say that we're very happy with DB4O, despite the problems we've encountered. The performance we've got has blown away some O/RM frameworks we tried. I recommend it.

Judah Himango
How did you get your server implementation to not block when processing a query? We've implemented (I HOPE!) a pretty naive client/server perf-test, and we observed that long-running queries block the server from processing others. Our perf-client operations are all read-only.
Peter Mounce
Couple things you can try: multiple databases, perhaps one for each user. You can use DB4O client/server mode, rather than embedded mode, which handles threading a little differently.
Judah Himango
Hi Judah!Regarding the issues you mentioned, activation depth is configured by default to 5, so db4o will stop activating objects at depth 5. You can also try transparent activation (now db4o support the native collections) and let db4o activate your objects only when necessary (when object is used).Regarding Linq, Native Queries and SODA in most cases you should have no perceptible performance difference (the most common case for such differences are related to db4o not finding required assemblies - such Mono.Cecil.dll, Db4objects.Db4o.Instrumentation and Cecil.FlowAnalysis).
Vagaus
Excellent answer.
Richard Clayton
+1  A: 

Main problem I've encountered with it is reporting. There just doesn't seem to be any way to run efficient reports against a db4o data source.

David Thibault
It's sometimes recommended to send data for reporting to a SQL server or a nice data warehouse for the reporting. It will be easier this way because you can denormalize this storage for easier reporting.
Davy Landman
+2  A: 

Hi!

Most native queries can and are efficiently converted into SODA queries behind the scenes so that should not make a difference. Using NQ is of course preferred as you remain in the realms of strong typed language. If you have problems getting NQ to use indexes please feel free to post your problem to the db4o forums and we'll try to help you out.

Goran

Goran
A: 

Judah, it sounds like you are not using transparent activation, which is a feature of the latest production version (7.4)? Perhaps if you specified the version you are using as there may be other issues which are now resolved in the latest version?

Keith Patton
At the time of writing, we were using 6.4. We're now using 7.8. However, we're still not using transparent activation, because it requires us to change all our list types to use DB4O lists.
Judah Himango