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.cs: TestSnapshotQueries
01private static void TestSnapshotQueries() 02 { 03 Console.WriteLine("Testing query performance on 10000 pilot objects in Snapshot mode"); 04 FillUpDB(10000); 05 IConfiguration configuration = Db4oFactory.NewConfiguration(); 06 configuration.Queries().EvaluationMode(QueryEvaluationMode.SNAPSHOT); 07 IObjectContainer db = Db4oFactory.OpenFile(configuration, Db4oFileName); 08 try 09 { 10 IQuery query = db.Query(); 11 query.Constrain(typeof(Pilot)); 12 query.Descend("_points").Constrain(99).Greater(); 13 DateTime dt1 = DateTime.UtcNow; 14 query.Execute(); 15 DateTime dt2 = DateTime.UtcNow; 16 TimeSpan diff = dt2 - dt1; 17 Console.WriteLine("Query execution time=" + diff.TotalMilliseconds + " ms"); 18 } 19 finally 20 { 21 db.Close(); 22 } 23 }
QueryModesExample.vb: TestSnapshotQueries
01Private Shared Sub TestSnapshotQueries() 02 Console.WriteLine("Testing query performance on 10000 pilot objects in Snapshot mode") 03 FillUpDB(10000) 04 Dim configuration As IConfiguration = Db4oFactory.NewConfiguration() 05 configuration.Queries.EvaluationMode(QueryEvaluationMode.SNAPSHOT) 06 Dim db As IObjectContainer = Db4oFactory.OpenFile(configuration, Db4oFileName) 07 Try 08 Dim query As IQuery = db.Query 09 query.Constrain(GetType(Pilot)) 10 query.Descend("_points").Constrain(99).Greater() 11 Dim dt1 As DateTime = DateTime.UtcNow 12 query.Execute() 13 Dim dt2 As DateTime = DateTime.UtcNow 14 Dim diff As TimeSpan = dt2 - dt1 15 Console.WriteLine("Query execution time=" + diff.TotalMilliseconds.ToString() + " ms") 16 Finally 17 db.Close() 18 End Try 19 End Sub

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.cs: TestSnapshotConcurrent
01private static void TestSnapshotConcurrent() 02 { 03 Console.WriteLine("Testing snapshot mode with concurrent modifications"); 04 FillUpDB(10); 05 IConfiguration configuration = Db4oFactory.NewConfiguration(); 06 configuration.Queries().EvaluationMode(QueryEvaluationMode.SNAPSHOT); 07 IObjectContainer db = Db4oFactory.OpenFile(configuration, Db4oFileName); 08 try 09 { 10 IQuery query1 = db.Query(); 11 query1.Constrain(typeof(Pilot)); 12 query1.Descend("_points").Constrain(5).Smaller(); 13 IObjectSet result1 = query1.Execute(); 14 15 IQuery query2 = db.Query(); 16 query2.Constrain(typeof(Pilot)); 17 query2.Descend("_points").Constrain(1); 18 IObjectSet result2 = query2.Execute(); 19 Pilot pilotToDelete = (Pilot)result2[0]; 20 Console.WriteLine("Pilot to be deleted: " + pilotToDelete); 21 db.Delete(pilotToDelete); 22 Pilot pilot = new Pilot("Tester", 2); 23 Console.WriteLine("Pilot to be added: " + pilot); 24 db.Set(pilot); 25 26 Console.WriteLine("Query result after changing from the same transaction"); 27 ListResult(result1); 28 } 29 finally 30 { 31 db.Close(); 32 } 33 }
QueryModesExample.vb: TestSnapshotConcurrent
01Private Shared Sub TestSnapshotConcurrent() 02 Console.WriteLine("Testing snapshot mode with concurrent modifications") 03 FillUpDB(10) 04 Dim configuration As IConfiguration = Db4oFactory.NewConfiguration() 05 configuration.Queries.EvaluationMode(QueryEvaluationMode.SNAPSHOT) 06 Dim db As IObjectContainer = Db4oFactory.OpenFile(configuration, Db4oFileName) 07 Try 08 Dim query1 As IQuery = db.Query 09 query1.Constrain(GetType(Pilot)) 10 query1.Descend("_points").Constrain(5).Smaller() 11 Dim result1 As IObjectSet = query1.Execute 12 Dim query2 As IQuery = db.Query 13 query2.Constrain(GetType(Pilot)) 14 query2.Descend("_points").Constrain(1) 15 Dim result2 As IObjectSet = query2.Execute 16 Dim pilotToDelete As Pilot = CType(result2(0), Pilot) 17 Console.WriteLine("Pilot to be deleted: " + pilotToDelete.ToString()) 18 db.Delete(pilotToDelete) 19 Dim pilot As Pilot = New Pilot("Tester", 2) 20 Console.WriteLine("Pilot to be added: " + pilot.ToString()) 21 db.Set(pilot) 22 Console.WriteLine("Query result after changing from the same transaction") 23 ListResult(result1) 24 Finally 25 db.Close() 26 End Try 27 End Sub

Pros and Cons for Snapshot Queries

Pros:

Cons:

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