Tuning the Results object

Probably the most commonly called method in the ObjectStore will be the ObjectStore.execute method, which returns a List of the results. This List is a Results object, which lazily fetches the data from the database as it is accessed. Calling the execute method doesn't actually touch the database at all. The first database access is made by the Results object. The Results object has several parameters which can be set, which will affect the performance of the data fetching.

The Results object fetches the data in blocks that we call batches, of a fixed size. You can set the batch size before the first batch has been fetched, but once the data has been fetched the batch size is fixed. The batches are held in a cache so that rows being read for a second time do not hit the database. However, the Java garbage collector is able to remove batches from the cache if the system becomes low on memory. Generally, larger batch sizes improves performance, especially with complex queries, however a complete batch must fit in memory. The batch size can be set by calling Results.setbatchSize().

The most common usage pattern of the Results object is likely to be that of iterating straight through all the rows in order, using the Iterator. This means that the data that will be required next is usually predictable. Therefore, by default the Results object performs prefetches. After rows have been accessed in sequence more than a few times, it will automatically fetch the next required batch in the background in order to speed up access when the next batch is reached. This behaviour can be switched off by calling Results.setNoPrefetch().

By default, an ObjectStore will check each batch fetch operation to see if it will take an unreasonable amount of time to execute. This is a feature to protect our main servers from overly complex queries run by users from the web site, however it has two downsides. Firstly it can lead to unexpected exceptions if the ObjectStore decides a query is too complex (and it may be wrong), and secondly the act of checking requires a call to the underlying database, which is usually an SQL server, which takes time. Therefore, this check can be switched off by calling Results.setNoExplain().

If possible, the ObjectStore will attempt to optimise the query being run, to make it run faster. This can be very effective with complex queries if there are several useful precomputed tables. However, the act of optimising the query takes time, so if the query is very simple, or if there are no precomputed tables then it is better to switch this off, which can be done by calling Results.setNoOptimise(). To see how to create precomputed tables, see the precomputing? page.

The Results object provides extra information that a List does not - an estimate of the number of rows in the List. This is provided through the Results.getInfo() method, which returns a ResultsInfo object.