Be very careful how you reference your SPListItem objects through the SharePoint API. I’ll say it again. Be very careful how you reference your SPListItem objects through the SharePoint API. Ok, now that you get the point that this will be a “learn from my mistakes and don’t do unsmart things like I did” post, let’s dig into what it was that I did poorly.
Scenario
For the past year I’ve been building custom .Net applications that are hosted through SharePoint. These application involve a number of SharePoint lists, external databases, custom web parts, and other SharePoint elements to provide functionality. About two weeks ago I received a message from one of our end users that a custom application was performing slowly. Specifically performance was slow when users were performing actions that interacted with the primary SharePoint list storing data for that app.
The Problem
I took a copy of the production site into a dev environment to investigate the code that was executing. After attaching the debugger and running through the code I quickly found pieces of code referencing SPListItem objects (like below) that were performing very poorly:
SPListItem myItem = SPContext.Current.Web.Lists["List Name"].Items.GetItemById(value);
// do updates on SPListItem retrieved
As it turns out the SPList I was referencing was fairly large at ~1000 items and weighing in over 150 MB. You see the problem with my above code is that I retrieved the SPListItem by first (unnecessarily) going through the Items member of the list. As I understand it, when doing so the executing code will attempt to resolve that entity and pull it from the database and into RAM (all 150 MB.) This causes the equivalent of a 50 car pile up in terms of performance with a single update taking more than 15 seconds.
The Solution
The solution is actually quite simple and I wish I had realized this during development. Instead of going through the Items member it is possible to call GetItemById(…) directly on the SPList as in the example below:
SPListItem myItem = SPContext.Current.Web.Lists["List Name"].GetItemById(value);
// do updates on SPListItem retrieved
After making this simple change performance skyrocketed and updates were back to less than a second.
Conclusion
When given the option between two solutions, usually the simplest is the best solution. In my scenario I was adding extra complexity going through the API the long way around to get to the objects I needed and it ended up hurting performance greatly. Luckily we were able to find and resolve the performance issue in a relatively short amount of time. Like I said at the beginning of the post, learn from my mistakes and hope it helps you.
-Frog Out
Image linked from http://www.freespirit.com/files/IMAGE/COVER/LARGE/BeCarefulSafe.jpg
Originally posted on: https://briantjackett.com/archive/2010/04/22/be-careful-when-referencing-splist.items.aspx#516334I will add to this. Don’t use the method GetItemByUniqueId. It uses a GUID and for some reason the system has to a scan through all GUIDs in the entire site collection. This in inefficient and takes a performance hit. The Id is good enough, it’s just an int.
LikeLike
Originally posted on: https://briantjackett.com/archive/2010/04/22/be-careful-when-referencing-splist.items.aspx#516355I’d like to add a little more to this.. if you really are after iterating over all the items in the list, you STILL shouldnt use SPList.Items! Put an SPQuery object together to use SPList.GetItems instead and be explicit about which fields you need. Internally SPList.Items does the same thing except it hydrates the SPListItem objects fully with ALL of the item’s data, which is why it can be so performance intensive..
LikeLike