5

I'm looking for the best performing means of querying for site data within a site collection. I need to query for all of the lists in either a particular SPWeb, or a set of SPWeb's, that contain a specific content type. The project I'm working on currently uses code like the following:

private void EnumerateChildWebs(SPWeb web, bool firstTime) {  
   if (!firstTime) {
      EnumerateListCol(web.Lists);
   }

   foreach (SPWeb child in web.Webs) {
      EnumerateChildWebs(child, false);
      child.Dispose();
   }
}

private void EnumerateListCol(SPListCollection spListCol) {
   SPList            list;
   SPContentTypeId   ctid;

   for (int i = 0; i < spListCol.Count; i++) {
      list = spListCol[i];

      if (list.ContentTypesEnabled && list.BaseType == SPBaseType.DocumentLibrary) {

         foreach (SPContentType ct in list.ContentTypes) {

            // [Omitted] - Code to check if the list contains a particular content type

            if (ct.ID matches the one we're looking for) {
               // Do something with the list
               break;
            }
         }
      }
   }
}

My question is, would it generally be better to use an SPSiteDataQuery to do this? It seems like it would yield much cleaner code, but what about performance? Is there any conventional wisdom around when to use SPSiteDataQuery? I've read some information on it on the web, but nothing that addresses my particular scenario.

2 Answers 2

4

This is a really interesting scenario (and one I looked at the other day), as there isn't much support in the API for this case - most of the methods provided are about aggregating list items rather than lists themselves. Consequently, if you try to use SPSiteDataQuery or one of the similar approaches (e.g. CrossListQueryCache) you can only retrieve resultsets of items, from which you would then derive the parent lists - whether this would be more efficient than your existing approach will likely come down to how many list items are being queried/retrieved in these 'intermediate' resultsets.

If you do look at this approach, finding items where the ContentTypeID starts with the appropriate site content type ID is the query to use.

The code I was writing the other day wasn't production code, but I'm 99% sure I arrived at the same result as you have. Whether SPSiteDataQuery or similar would provide better performance could only be proven by testing it out in our respective sites I think, since the number of lists/number of list items/indexed columns etc. would all be factors which would have a big impact. Having < 10 lists with < 10 items each is clearly very different from 1000 lists with 100,000 items each.

P.S. As a general reference on aggregation techniques, the following are interesting reading:

1
  • That's just the information I was looking for. I just wanted to make sure I wasn't missing something obvious. Thanks again for your help! Apr 9, 2010 at 18:42
2

I'm not sure if it's applicable here, but on the DVWP side of things, there's a DataSourceMode="ListofLists" which returns, you guessed it, a list of lists. The Web Services have analogous functionality with the Lists.GetListCollection Method. I would assume that since those two layers allow you to access information about lists without looking at their items that the API would provide similar functionality.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.