Snapshot Queries

Snapshot mode allows you to get the advantages of the Lazy queries avoiding their side effects. When query is executed, the query processor chooses the best indexes, does all index processing and creates a snapshot of the index at this point in time. Non-indexed constraints are evaluated lazily when the application iterates through the ObjectSet resultset of the query.

QueryModesExample.java: testSnapshotQueries
01public static void testSnapshotQueries() { 02 System.out.println("Testing query performance on 10000 pilot objects in Snapshot mode"); 03 fillUpDB(10000); 04 ObjectContainer db = Db4o.openFile(YAPFILENAME); 05 try { 06 db.ext().configure().queries().evaluationMode(QueryEvaluationMode.SNAPSHOT); 07 QueryStats stats = new QueryStats(); 08 stats.connect(db); 09 Query query = db.query(); 10 query.constrain(Pilot.class); 11 query.descend("points").constrain(99).greater(); 12 query.execute(); 13 long executionTime = stats.executionTime(); 14 System.out.println("Query execution time: " + executionTime); 15 } finally { 16 db.close(); 17 } 18 }
 



Snapshot queries ensure better performance than Immediate queries, but the performance will depend on the size of the resultset.

As the snapshot of the results is kept in memory the result set is not affected by the changes from the caller or from another transaction (compare the results of this code snippet to the one from Lazy Queries topic):

QueryModesExample.java: testSnapshotConcurrent
01public static void testSnapshotConcurrent() { 02 System.out.println("Testing snapshot mode with concurrent modifications"); 03 fillUpDB(10); 04 ObjectContainer db = Db4o.openFile(YAPFILENAME); 05 try { 06 db.ext().configure().queries().evaluationMode(QueryEvaluationMode.SNAPSHOT); 07 Query query1 = db.query(); 08 query1.constrain(Pilot.class); 09 query1.descend("points").constrain(5).smaller(); 10 ObjectSet result1 = query1.execute(); 11 12 Query query2 = db.query(); 13 query2.constrain(Pilot.class); 14 query2.descend("points").constrain(1); 15 ObjectSet result2 = query2.execute(); 16 Pilot pilotToDelete = (Pilot)result2.get(0); 17 System.out.println("Pilot to be deleted: " + pilotToDelete); 18 db.delete(pilotToDelete); 19 Pilot pilot = new Pilot("Tester",2); 20 System.out.println("Pilot to be added: " + pilot); 21 db.set(pilot); 22 23 System.out.println("Query result after changing from the same transaction"); 24 listResult(result1); 25 } finally { 26 db.close(); 27 } 28 }
 

Pros and Cons for Snapshot Queries

Pros:

  • Index processing will happen without possible side effects from changes made by the caller or by other transaction.
  • Since index processing is fast, a server will not be blocked for a long time.

Cons:

  • The entire candidate index will be loaded into memory. It will stay there until the query ObjectSet is garbage collected. In a C/S setup, the memory will be used on the server side

Client/Server applications with the risk of concurrent modifications should prefer Snapshot mode to avoid side effects from other transactions.