Set ObjectTrackingEnabled = false when reading
By Anatoly Mironov
In LINQ 2 SP we work with a data context. By default a data context has the property ObjectTrackingEnabled = true. This property is crucial for all other operations in CRUD except Read. I performed a mini experiment. I created 20 000 items in my task list. Every seventh item contains “pärla”. Allright, here is what I found out:
2857 / 20 000 items
ObjectTrackingEnabled = true
07s.405ms
ObjectTrackingEnabled = false
01s.232ms
Sharepoint as a developer platform. With ObjectTrackingEnabled it takes 6 times more time to read the list items: whole 7,5 seconds. It would be a catastrophy if you would run this code to retrieve some items in your webpart which runs synchronously in the main thread. The best SharePoint book from a developer perspective (SharePoint 2010 as a developer platform) explains ObjectTrackingEnabled:
Track Changes The LINQ to SharePoint provider checks changes made in the database against its current state. This is the default behavior. If you access the lists in a read-only manner, the tracking can be suppressed to optimize performance:
ctx.ObjectTrackingEnabled = false;
Here is the code which I ran to get the results:
Console.WriteLine("Oppgaver, 20 000 items");
var sw = new Stopwatch();
Console.WriteLine("Retrieving items containing pärla");
Console.WriteLine("\\n");
Console.WriteLine("\*\*\*\* ObjectTrackingEnabled=true (default) \*\*\*\*");
sw.Start();
using (var ctx = new OppgaverDataContext("http://takana/"))
{
var tasks = ctx.Oppgaver.Where(t=> t.Title.Contains("pärla")).ToList();
Console.WriteLine("\\tcount: " + tasks.Count());
}
sw.Stop();
var elapsed = String.Format("{0:00}s:{1:000}ms", sw.Elapsed.Seconds, sw.Elapsed.Milliseconds);
Console.WriteLine("\\ttime:\\t" + elapsed);
sw = new Stopwatch();
Console.WriteLine("\\n");
Console.WriteLine("\*\*\*\* ObjectTrackingEnabled=false \*\*\*\*");
sw.Start();
using (var ctx = new OppgaverDataContext("http://takana/") { ObjectTrackingEnabled = false })
{
var tasks = ctx.Oppgaver.Where(t => t.Title.Contains("pärla")).ToList();
Console.WriteLine("\\tcount: " + tasks.Count());
}
sw.Stop();
elapsed = String.Format("{0:00}s:{1:000}ms", sw.Elapsed.Seconds, sw.Elapsed.Milliseconds);
Console.WriteLine("\\ttime:\\t" + elapsed);