none
Performance Guidance and SPList.Items.Add - no need to avoid using it

    Pertanyaan

  • I've been reviewing a rather complex SharePoint application to pinpoint some performance issues and noticed that there was some lines of code which were something like:

    SPListItem newItem = theList.Items.Add();

    The list in question has over 44k items in it so I immediately thought that the issue was the use of Items.Add() as we have the MSDN article:

    http://msdn.microsoft.com/en-us/library/bb687949(v=office.12).aspx

    Telling us that using SPList.Items is "very bad", a quick google/bing will uncover a raft of blogs/articles stating the same thing, most of the articles recommend using a convention where you get the SPListItemCollection using the SPList.GetItems() method passing in some sort of dummy or empty query.

    The thing was when I examined the ULS logs I did notice loads of entries with the Category Database with a message stating that a List item query elapsed time was in the region of anything between 4k - 350k milliseconds, but none of the entries were for the list that was being added to using SPList.Items.Add(). The site had lots of other lists with around 20k items in them and it was these lists that appeared to be the source of the ULS log entries (there's other code I've already pinpointed that is the source of these issues).

    I then put together a basic list (just added one number column with a default value of 123) and populated the list with 25k items.

    Then I wrote a simple console app which added items to the list using empty SPQuery objects and using the SPList.Items.Add() method. I did not get any performance differences using the SPList.Items.Add() method, each add operation only took in the region of 300 milliseconds.

    Just to check other things I then accessed a SPListItem from the SPList.Items[Guid listItemUniqueId] accessor just to make sure I was able to see the performance issue I would expect with such large lists and sure enough using this accessor would take around 8 seconds to complete.

    The console code I used is below:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using Microsoft.SharePoint;

    namespace ScratchConsole
    {
     class Program
     {
      static void Main(string[] args)
      {
       using(SPSite siteCollection = new SPSite("http://sharepointdevbox:1001"))
       using (SPWeb site = siteCollection.OpenWeb())
       {
        SPQuery minusOneQuery = new SPQuery();
        minusOneQuery.Query = "<Where><Eq><FieldRef Name='ID' /><Value Type='Number'>-1</Value></Eq></Where>";
        SPQuery emptyStringQuery = new SPQuery();
        emptyStringQuery.Query = String.Empty;

        SPQuery currentItemQuery = new SPQuery();
        currentItemQuery.Query = "<Where><Eq><FieldRef Name='ID' /><Value Type='Number'>10000</Value></Eq></Where>";
       
        SPList testList = site.GetList("/Lists/Test");
        SPListItem currentItem = testList.GetItems(currentItemQuery)[0];
        Guid currentItemUniqueId = currentItem.UniqueId;
        SPListItem newItem = null;
        switch (args[0])
        {
         case "1":
          Console.WriteLine("Starting with minusOneQuery\nTime:{0}", DateTime.Now.ToString("HH:mm:ss.fffff"));
          newItem = testList.GetItems(minusOneQuery).Add();
          SPListItem currentItemAgain1 = testList.GetItemByUniqueId(currentItemUniqueId);
          break;
         case "2":
          Console.WriteLine("Starting with emptyStringQuery\nTime:{0}", DateTime.Now.ToString("HH:mm:ss.fffff"));
          newItem = testList.GetItems(emptyStringQuery).Add();
          SPListItem currentItemAgain2 = testList.GetItemByUniqueId(currentItemUniqueId);
          break;
         case "3":
          Console.WriteLine("Starting with Items\nTime:{0}", DateTime.Now.ToString("HH:mm:ss.fffff"));
          newItem = testList.Items.Add();
          //Remove this line below if all you want to do is test the adding of items.
          SPListItem currentItemAgain3 = testList.Items[currentItemUniqueId];
           break;
        }
         
        newItem["Title"] = "TitleAdded";
        newItem.Update();
        Console.WriteLine("Time:{0}", DateTime.Now.ToString("HH:mm:ss.fffff"));    
       }   
      }
     }
    }
     

    Anyone got any comments on this?

     


    http://www.linkedin.com/in/colinrippey http://www.facebook.com/colinrippey http://twitter.com/finarne http://finarne.w
    • Diedit oleh Mike Walsh FIN 16 Maret 2011 13:10 still the bad boy removed. Have normal titles
    • Diedit oleh Ripster 16 Maret 2011 22:00
    16 Maret 2011 11:45

Semua Balasan

  • Hi,

    If you want to add bulk items quickly then you must use SPWeb.ProcessBatchData() . Please find link for your ref.

    http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spweb.processbatchdata.aspx

     


    thanksArup MCTS - SharePoint

    Play Sudoku Online
    16 Maret 2011 12:33
  • Thanks for the reply but my question has nothing to do with adding bulk items quickly, my questions concerns the use of SPList.Items.Add() to add an item to a list. The guidance around the web indicates that you should avoid the SPList.Items property at all costs, my research indicates that there's no performance penalty in using SPList.Items.Add() but there is if you use SPList.Items[Guid listItemUniqueId].

     


    http://www.linkedin.com/in/colinrippey http://www.facebook.com/colinrippey http://twitter.com/finarne http://finarne.wordpress.com
    16 Maret 2011 21:58
  • Hi Ripster!

    I'm using this way it's very quickly.

    try to use something like it:

    using (SPWeb web = new SPSite(SPContext.Current.Site.Url).OpenWeb()) { SPListItem item = web.GetList(Listas.LPChecklistCabecalho).AddItem();

    //fill some properties
    item["Title"] = "blablabla";

    web.AllowUnsafeUpdates = true;        item.Update(); web.AllowUnsafeUpdates = false;

    }

    Cheers!


    jbdevpoa


    10 Juli 2012 20:02