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.
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.Milliseconds + " ms"); 18
} 19
finally 20
{ 21
db.Close(); 22
} 23
}
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.Milliseconds.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):
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
}
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:
Cons:
Client/Server applications with the risk of concurrent modifications should prefer Snapshot mode to avoid side effects from other transactions.