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.
01public static void TestSnapshotQueries() 02
{ 03
Console.WriteLine("Testing query performance on 10000 pilot objects in Snapshot mode"); 04
FillUpDB(10000); 05
IObjectContainer db = Db4oFactory.OpenFile(YapFileName); 06
try 07
{ 08
db.Ext().Configure().Queries().EvaluationMode(QueryEvaluationMode.SNAPSHOT); 09
IQuery query = db.Query(); 10
query.Constrain(typeof(Pilot)); 11
query.Descend("_points").Constrain(99).Greater(); 12
DateTime dt1 = DateTime.UtcNow; 13
query.Execute(); 14
DateTime dt2 = DateTime.UtcNow; 15
TimeSpan diff = dt2 - dt1; 16
Console.WriteLine("Query execution time=" + diff.Milliseconds + " ms"); 17
} 18
finally 19
{ 20
db.Close(); 21
} 22
}
01Public Shared Sub TestSnapshotQueries() 02
Console.WriteLine("Testing query performance on 10000 pilot objects in Snapshot mode") 03
FillUpDB(10000) 04
Dim db As IObjectContainer = Db4oFactory.OpenFile(YapFileName) 05
Try 06
db.Ext.Configure.Queries.EvaluationMode(QueryEvaluationMode.SNAPSHOT) 07
Dim query As IQuery = db.Query 08
query.Constrain(GetType(Pilot)) 09
query.Descend("_points").Constrain(99).Greater() 10
Dim dt1 As DateTime = DateTime.UtcNow 11
query.Execute() 12
Dim dt2 As DateTime = DateTime.UtcNow 13
Dim diff As TimeSpan = dt2 - dt1 14
Console.WriteLine("Query execution time=" + diff.Milliseconds.ToString() + " ms") 15
Finally 16
db.Close() 17
End Try 18
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):
01public static void TestSnapshotConcurrent() 02
{ 03
Console.WriteLine("Testing snapshot mode with concurrent modifications"); 04
FillUpDB(10); 05
IObjectContainer db = Db4oFactory.OpenFile(YapFileName); 06
try 07
{ 08
db.Ext().Configure().Queries().EvaluationMode(QueryEvaluationMode.SNAPSHOT); 09
IQuery query1 = db.Query(); 10
query1.Constrain(typeof(Pilot)); 11
query1.Descend("_points").Constrain(5).Smaller(); 12
IObjectSet result1 = query1.Execute(); 13
14
IQuery query2 = db.Query(); 15
query2.Constrain(typeof(Pilot)); 16
query2.Descend("_points").Constrain(1); 17
IObjectSet result2 = query2.Execute(); 18
Pilot pilotToDelete = (Pilot)result2[0]; 19
Console.WriteLine("Pilot to be deleted: " + pilotToDelete); 20
db.Delete(pilotToDelete); 21
Pilot pilot = new Pilot("Tester", 2); 22
Console.WriteLine("Pilot to be added: " + pilot); 23
db.Set(pilot); 24
25
Console.WriteLine("Query result after changing from the same transaction"); 26
ListResult(result1); 27
} 28
finally 29
{ 30
db.Close(); 31
} 32
}
01Public Shared Sub TestSnapshotConcurrent() 02
Console.WriteLine("Testing snapshot mode with concurrent modifications") 03
FillUpDB(10) 04
Dim db As IObjectContainer = Db4oFactory.OpenFile(YapFileName) 05
Try 06
db.Ext.Configure.Queries.EvaluationMode(QueryEvaluationMode.SNAPSHOT) 07
Dim query1 As IQuery = db.Query 08
query1.Constrain(GetType(Pilot)) 09
query1.Descend("_points").Constrain(5).Smaller() 10
Dim result1 As IObjectSet = query1.Execute 11
Dim query2 As IQuery = db.Query 12
query2.Constrain(GetType(Pilot)) 13
query2.Descend("_points").Constrain(1) 14
Dim result2 As IObjectSet = query2.Execute 15
Dim pilotToDelete As Pilot = CType(result2(0), Pilot) 16
Console.WriteLine("Pilot to be deleted: " + pilotToDelete.ToString()) 17
db.Delete(pilotToDelete) 18
Dim pilot As Pilot = New Pilot("Tester", 2) 19
Console.WriteLine("Pilot to be added: " + pilot.ToString()) 20
db.Set(pilot) 21
Console.WriteLine("Query result after changing from the same transaction") 22
ListResult(result1) 23
Finally 24
db.Close() 25
End Try 26
End Sub
Pros:
Cons:
Client/Server applications with the risk of concurrent modifications should prefer Snapshot mode to avoid side effects from other transactions.