Quantcast
Channel: MetroStar Systems Blog » C#
Viewing all articles
Browse latest Browse all 11

Taking SPQuery To The Max

0
0

Recently I was working on a project which utilizes SharePoint to store backend data for a ticketing system. The layout of the data is a bit relational, much like SQL tables. In fact, some would say that it probably should be stored in SQL directly, but I disagree. I agree that using SharePoint lists will never be quite as fast as SQL tables, however I do think that using some tricks you can make your SharePoint data access incredibly fast. And honestly, I take advantage of the SharePoint Object Model whenever possible.

Before getting into that though, I’ll explain a little further about how I came to this…as I mentioned I am accessing SharePoint list data. The list itself contains about 5000 items and it has a few lookups to another list which contains user information. Additionally the items in the list have unique permissions which end up with a combination of SharePoint groups, depending on which group the ticket is assigned to. This data is then aggregated into a few group dashboard pages.

I noticed one day that the dashboard page was taking excessively long to load for some users. The load time was averaging about 6 seconds. When I were to load the page however, it would load almost instantly. After doing some testing and profiling I determined that the root of the issue was a combination of the unique item permissions and the lookup columns.

So after trying a few things I had the idea of running the data querying in an elevated context. Low and behold that fixed the problem. Please note this does mean that security trimming of items in this process is essentially eliminated. In my case however that was not an issue because each ticket has an Assigned Group, which I can use in my query to only return applicable tickets. So in the end the user will still only see items they have access to.

To illustrate this, I’ve created a similar scenario which utilizes a list which has a lookup to another list. The base list contains 10000 items, each of which have unique permissions. And I’ve updated each items permissions to give my test group access to every other item.

Below is a standard code block using SPQuery to access the data, which just runs a counter for the example. As far as I know, I am doing everything I can to Maximize performance on the query…I am setting the ViewFields property to ensure only the specified fields are returned. I’m also loading the list items into an SPListItemCollection instead of calling the GetItems method inside of the foreach loop, which seems to be a common mistake. See code below:

SPList list = SPContext.Current.Web.Lists["Test List"];
SPQuery query = new SPQuery();
query.ViewFields = "<FieldRef Name='Title' /><FieldRef Name='LookupValue' />";
query.Query = "<Where><Eq><FieldRef Name='LookupValue' /><Value Type='Lookup'>Value 1</Value></Eq></Where>";
SPListItemCollection listItems = list.GetItems(query);
int counter = 0;
foreach (SPListItem item in listItems)
{
    counter++;
}

This query returns 700+ items and takes about 30 seconds to load…incredibly slow.

And finally to take this query to the Max, the below code block uses the same code, but runs the query in an elevated context:

SPSite site = SPContext.Current.Site;
SPWeb web = SPContext.Current.Web;
int counter = 0;
SPSecurity.RunWithElevatedPrivileges(delegate()
{
    using (SPSite elevatedSite = new SPSite(site.ID))
    {
        using (SPWeb elevatedWeb = elevatedSite.OpenWeb(web.ID))
        {
            SPList list = elevatedWeb.Lists["Test List"];
            SPQuery query = new SPQuery();
            query.ViewFields = "<FieldRef Name='Title' /><FieldRef Name='LookupValue' />";
            query.Query = "<Where><Eq><FieldRef Name='LookupValue' /><Value Type='Lookup'>Value 1</Value></Eq></Where>";
            SPListItemCollection listItems = list.GetItems(query);
            foreach (SPListItem item in listItems)
            {
                counter++;
            }
        }
    }
});

This query returns the same 700+ items and takes about 0.277 seconds to load. A HUGE improvement!

So to summarize. SPQuery is crazy fast, however it can get bogged down by lists with a lot of unique item permissions. So to Super Charge your code, run it elevated! And just to say it one more time…make sure you are doing your due diligence to ensure your query is not returning items that would usually be security trimmed out.

And as a final note, if you try this for yourself, make sure you are testing this with a non-admin account, because you won’t notice a difference if you’re already an admin.

The post Taking SPQuery To The Max appeared first on MetroStar Systems Blog.


Viewing all articles
Browse latest Browse all 11

Latest Images

Trending Articles





Latest Images