14. Native Query OptimizationNative Queries will run out of the box in any environment. If an optimizer is present in the CLASSPATH and if optimisation is turned on, Native Queries will be converted to SODA queries where this is possible, allowing db4o to use indexes and optimized internal comparison algorithms. If no optimizer is found in the CLASSPATH or if optimization is turned off, Native Quer may be executed by instantiating all objects, using SODA Evaluations. Naturally performance will not be as good in this case. The Native Query optimizer is still under development to eventually "understand" all Java constructs. Current optimization supports the following constructs well: - compile-time constants - simple member access - primitive comparisons - #equals() on primitive wrappers and Strings - #contains()/#startsWith()/#endsWith() for Strings - arithmetic expressions - boolean expressions - static field access - array access for static/predicate fields - arbitrary method calls on static/predicate fields (without candidate based params) - candidate methods composed of the above - chained combinations of the above This list will constantly grow with the latest versions of db4o. Note that the current implementation doesn't support polymorphism and multiline methods yet. db4o for Java supplies three different possibilities to run optimized native queries, optimization at (1) query execution time (2) deployment time (3) class loading time The three options are described in the following: 14.1. Optimization at query execution timeNote: This will not work with JDK1.1. To enable code analysis and optimization of native query expressions at query query execution time, you just have to add db4o-6.1-nqopt.jar and bloat-6.1.jar to your CLASSPATH. Optimization can be turned on and off with the following configuration setting:
14.2. Instrumenting class filesNote: Instrumented optimized classes will work with JDK1.1, but the optimization process itself requires at least JDK 1.2. File instrumentation can be done either programmatically or during an Ant build. 14.2.1. Programmatic InstrumentationTo instrument all predicate classes in directory 'orig' whose package name starts with 'my.package' and store the modified files below directory 'instrumented', ensure that db4o-6.1-nqopt.jar and bloat-6.1.jar are in your CLASSPATH and use code like the following:
14.2.2. Ant InstrumentationAn equivalent Ant target might look like this:
All non-Predicate classes will just be copied to the target directory without modification. 14.3. Instrumenting classes at load timeNote: This will not work with JDK1.1. If classes of an existing application are to be instrumented when they are loaded, a special ClassLoader needs to be used to run your application, com.db4o.nativequery.main.Db4oEnhancingClassLoader. Again db4o-6.1-nqopt.jar and bloat-6.1.jar need to be in the CLASSPATH. All the native query code of your application would need to run in this ClassLoader. If we assume that you have a static starting method "goNative" in a class named "my.StarterClass", here is how you could run this method within the special native query ClassLoader:
To start a full application in optimized mode, you can use the Db4oRunner utility class. If you would normally start your application like this:
start Db4oRunner with the fully qualified name of your main class as the first argument and the actual arguments appended:
Further options: - Setting the system class loader (-Djava.system.class.loader=com.db4o.nativequery.main.Db4oEnhancingClassLoader) - Configuring Tomcat to use the optimizing class loader (Tomcat server.xml 14.4. Monitoring optimizationThis feature still is quite basic but it will soon be improved. Currently you can only attach a listener to the ObjectContainer:
The listener will be notified on each native query call and will be passed the Predicate object processed, the optimized expression tree (if successful) and the success status of the optimization run: YapStream.UNOPTIMIZED ("UNOPTIMIZED") if the predicate could not be optimized and is run in unoptimized mode YapStream.PREOPTIMIZED ("PREOPTIMIZED") if the predicate already was optimized (due to class file or load time instrumentation) YapStream.DYNOPTIMIZED ("DYNOPTIMIZED") if the predicate was optimized at query execution time -- generated by Doctor courtesy of db4objects Inc. |