惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tenable Blog
Last Week in AI
Last Week in AI
P
Proofpoint News Feed
Engineering at Meta
Engineering at Meta
H
Help Net Security
F
Fortinet All Blogs
MyScale Blog
MyScale Blog
宝玉的分享
宝玉的分享
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 司徒正美
量子位
N
Netflix TechBlog - Medium
Apple Machine Learning Research
Apple Machine Learning Research
小众软件
小众软件
Recorded Future
Recorded Future
博客园 - 三生石上(FineUI控件)
Vercel News
Vercel News
aimingoo的专栏
aimingoo的专栏
I
InfoQ
Microsoft Security Blog
Microsoft Security Blog
Scott Helme
Scott Helme
The Last Watchdog
The Last Watchdog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
IT之家
IT之家
AI
AI
WordPress大学
WordPress大学
Security Archives - TechRepublic
Security Archives - TechRepublic
Google Online Security Blog
Google Online Security Blog
U
Unit 42
V2EX - 技术
V2EX - 技术
MongoDB | Blog
MongoDB | Blog
Schneier on Security
Schneier on Security
博客园 - Franky
H
Heimdal Security Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Jina AI
Jina AI
W
WeLiveSecurity
P
Privacy & Cybersecurity Law Blog
Cloudbric
Cloudbric
B
Blog RSS Feed
N
News | PayPal Newsroom
S
Securelist
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
I
Intezer
Hacker News - Newest:
Hacker News - Newest: "LLM"
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
博客园_首页
罗磊的独立博客
H
Hackread – Cybersecurity News, Data Breaches, AI and More
雷峰网
雷峰网

博客园 - 赏梅斋

直接访问K2数据库找未归档正在进行中的流程的SQL语句 SharePoint学习笔记1--Asp.net与SharePoint的Session机制 安装Lync Server前端必备组件Wmf2008R2时失败的问题 域环境安装SQLServer时出现“帐户名与安全标识之间无任何映射”的问题 网络发现不能启用的问题 sharepoint 2010 与sqlserver denali的支持性安装测试 SPES2011开始注册了! K2 Blackpearl 4.5 怎样配置SQLUM SharePoint2010企业开发最佳实践(九)---- 事件接收器的最佳做法 SharePoint2010企业开发最佳实践(八)---- SPWeb 对象 SharePoint2010企业开发最佳实践(七)---- SPSite 对象 SharePoint2010企业开发最佳实践(六)---- 用于确保释放对象的编码技术 SharePoint2010企业开发最佳实践(五)---- 查找错误释放的对象 SharePoint2010企业开发最佳实践(四)---- 关于使用可释放的 SharePoint 对象的介绍 SharePoint2010企业开发最佳实践(三)---- 对象缓存技术 SharePoint2010企业开发最佳实践(一)----在 SharePoint Server 中编写有效代码 修改MOSS服务器名称 赏梅斋最新推出论坛Microsoft Information Worker 2008年3月19日主题讨论日
SharePoint2010企业开发最佳实践(二)---- 处理大型文件夹和列表
赏梅斋 · 2011-02-11 · via 博客园 - 赏梅斋

当文件夹和列表的大小增加时,您必须设计处理它们的自定义代码以优化性能。否则,您的应用程序将会运行缓慢,并可能引起服务或页面加载超时。处理大文件夹和列表时主要需要关注以下两个方面:

  • 查询限制,随着时间的推移,当您的网站不断发展并且您的查询开始返回超过查询阈值的项目时,这会引发您的代码行为发生不可预测的意外更改。

  • 从大文件夹和列表中高效检索项目。

为了解决这两个问题,您必须了解对象模型是如何与文件夹和列表交互的。

大列表查询的限制

Microsoft SharePoint Foundation 2010 和 Microsoft SharePoint Server 2010 应用 5,000 个项目的默认查询阈值。任何依赖可能会超过此最大值的查询结果集的自定义代码都不会按预期执行。如果列表中包含 5,000 多个项目并且这些项目包含未编入查询条件索引的字段,那么对这些列表的查询也将失败,因为这些查询必须扫描列表中的所有行。可按照下面列出的步骤查看并增加此限制或允许对象模型替代此限制:

查看并增加此阈值或允许对象模型替代此阈值

  1. 在“管理中心”网站上的“应用程序管理”下,单击“管理 Web 应用程序”。

  2. 单击“常规设置”,然后单击“资源限制”。

  3. 查看并更新阈值或允许对象模型替代限制。

处理文件夹和列表

Microsoft SharePoint Foundation 2010 和 Microsoft SharePoint Server 2010 应用 5,000 个项目的默认查询阈值。任何依赖可能会超过此最大值的查询结果集的自定义代码都不会按预期执行。如果列表中包含 5,000 多个项目并且这些项目包含未编入查询条件索引的字段,那么对这些列表的查询也将失败,因为这些查询必须扫描列表中的所有行。可按照下面列出的步骤查看并增加此限制或允许对象模型替代此限制:

用于解决在处理大文件夹和列表时的性能问题的以下建议基于 Steve Peschka 的白皮书在 Office SharePoint Server 2007 中处理大型列表(英文)中报告的测试结果。这些建议也适用于 Microsoft SharePoint Server 2010。在处理文件夹和列表时:

  • 不要使用 SPList.Items

    SPList.Items 会选择所有子文件夹中的所有项目,包括列表中的所有字段。为每个用例使用以下替代项。

    • 添加项目

      不要调用 SPList.Items.Add,而是使用 SPList.AddItem

    • 检索列表中的所有项目

      不要使用 SPList.Items,而是使用 SPList.GetItems(SPQuery query) 。根据需要应用筛选器,并只指定所需字段以使查询更高效。如果列表包含的项目超过 2,000 个,请按不超过 2,000 个项目的增量对列表进行分页。下面的代码示例演示如何对大型列表进行分页。

      好的编码实践

      使用 SPList.GetItems 检索项目

  SPQuery query = new SPQuery();
SPListItemCollection spListItems ; 
string lastItemIdOnPage = null; // Page position.
int itemCount = 2000
 
while (itemCount == 2000)
{
    // Include only the fields you will use.
    query.ViewFields = "<FieldRef Name=\"ID\"/><FieldRef Name=\"ContentTypeId\"/>";  
    query.RowLimit = 2000; // Only select the top 2000.
    // Include items in a subfolder (if necessary).
    query.ViewAttributes = "Scope=\"Recursive\"";
    StringBuilder sb = new StringBuilder();
    // To make the query order by ID and stop scanning the table, specify the OrderBy override attribute.
    sb.Append("<OrderBy Override=\"TRUE\"><FieldRef Name=\"ID\"/></OrderBy>");
    //.. Append more text as necessary ..
    query.Query = sb.ToString();
    // Get 2,000 more items.
 
    SPListItemCollectionPosition pos = new SPListItemCollectionPosition(lastItemIdOnPage);
    query.ListItemCollectionPosition = pos; //Page info.
    spListItems = spList.GetItems(query);
    lastItemIdOnPage = spListItems.ListItemCollectionPosition.PagingInfo;
    // Code to enumerate the spListItems.
    // If itemCount <2000, finish the enumeration.
    itemCount = spListItems.Count;

}

     下面的示例演示如何枚举大型列表并对其进行分页。

     SPWeb oWebsite = SPContext.Current.Web;
SPList oList = oWebsite.Lists["Announcements"];

SPQuery oQuery = new SPQuery();
oQuery.RowLimit = 10;
int intIndex = 1;

do
{
    Response.Write("<BR>Page: " + intIndex + "<BR>");
    SPListItemCollection collListItems = oList.GetItems(oQuery);

    foreach (SPListItem oListItem in collListItems)
    {
        Response.Write(SPEncode.HtmlEncode(oListItem["Title"].ToString()) +"<BR>");
    }

    oQuery.ListItemCollectionPosition = collListItems.ListItemCollectionPosition;
    intIndex++;
} while (oQuery.ListItemCollectionPosition != null);

   
    • 按标识符获取项目

      不要使用 SPList.Items.GetItemById,而是使用 SPList.GetItemById(int id, string field1, params string[] fields)。指定项目标识符和所需字段。

  • 不要枚举整个 SPList.Items 集合或 SPFolder.Files 集合。

    表 1 中的左边一列列出了一些方法和属性,如果使用这些方法和属性,将会枚举整个 SPList.Items 集合并导致大型列表性能低下和存在限制。请改用右边一列中列出的性能较好的替代项。

    表 1. 枚举 SPList.Items 的替代项

    性能较差的方法和属性

    性能较好的替代项

    SPList.Items.Count

    SPList.ItemCount

    SPList.Items.XmlDataSchema

    创建一个 SPQuery 对象以便只检索所需项目。

    SPList.Items.NumberOfFields

    创建一个 SPQuery 对象(指定 ViewFields)以便只检索所需项目。

    SPList.Items[System.Guid]

    SPList.GetItemByUniqueId(System.Guid)

    SPList.Items[System.Int32]

    SPList.GetItemById(System.Int32)

    SPList.Items.GetItemById(System.Int32)

    SPList.GetItemById(System.Int32)

    SPList.Items.ReorderItems(System.Boolean[],System.Int32[],System.Int32)

    使用 SPQuery 执行分页查询并在每页中对项目重新排序。

    SPList.Items.ListItemCollectionPosition

    ContentIterator.ProcessListItems(SPList, ContentIterator.ItemProcessor, ContentIterator.ItemProcessorErrorCallout) (仅限 Microsoft SharePoint Server 2010)

    SPList.Items.ListItemCollectionPosition

    ContentIterator.ProcessListItems(SPList, ContentIterator.ItemProcessor, ContentIterator.ItemProcessorErrorCallout) (仅限 SharePoint Server 2010)

    注释 注释

    使用 SPList.ItemCount 属性是检索列表中的项目数的推荐方法。但是,由于为了性能而优化此属性会产生副作用,因此该属性偶尔会返回意外结果。例如,如果您需要精确的项目数,则应使用性能较差的 GetItems(SPQuery query),如前面的代码示例所示。

  • 尽可能使用列表的 GUID 或 URL 作为键来获取对列表的引用。

    可以使用列表的 GUID 或显示名称作为索引器从 SPWeb.Lists 属性中检索 SPList 对象。使用 SPWeb.Lists[GUID]SPWeb.GetList(strURL) 总是比使用 SPWeb.Lists[strDisplayName] 更可取。最好使用 GUID,因为它是唯一的、永久的,并且只需要单次数据库查找。显示名称索引器检索网站中所有列表的名称,然后对它们执行字符串比较。如果您有列表 URL 而没有 GUID,则可以使用 SPWeb 中的 GetList 方法在内容数据库中查找列表的 GUID,然后再检索列表。

  • 不要枚举整个 SPFolder.Files 集合。

    表 2 中的左边一列列出了使 SPFolder.Files 集合膨胀并导致大型列表性能低下和存在限制的方法和属性。请改用右边一列中性能较好的替代项。

    表 2. SPFolders.Files 的替代项

    性能较差的方法和属性

    性能较好的替代项

    SPFolder.Files.Count

    SPFolder.ItemCount

    SPFolder.Files.GetEnumerator()

    ContentIterator.ProcessFilesInFolder(SPFolder, System.Boolean, ContentIterator.FileProcessor, ContentIterator.FileProcessorErrorCallout) (仅限 SharePoint Server 2010)

    SPFolder.Files[System.String]

    ContentIterator.GetFileInFolder(SPFolder, System.String) 或者 SPFolder.ParentWeb.GetFile(SPUrlUtility.CombineUrl(SPFolder.Url, System.String)(仅限 SharePoint Server 2010)

    SPFolder.Files[System.Int32]

    不要使用。切换为 ContentIterator.ProcessFilesInFolder 并在迭代过程中统计项数。(仅限 SharePoint Server 2010)