在this文章中,microsoft解释了为什么有5000项限制。但是我何时可以访问超过5000件物品?
实施例: 我有一个包含50 000个项目的列表,我执行一个行限制为50的caml查询.Sharepoint是锁定数据库还是只有50行? sharepoint如何知道是否只有一些行,或整个数据库应该被锁定?或者取决于它本身?
锁是否影响整个服务器场或仅影响当前列表,因为sharepoint没有为每个列表创建一个自己的表?
答案 0 :(得分:1)
在SharePoint 2010中,当您在大型列表上执行SPQuery时,您将获得异常"禁止尝试的操作,因为它超出了管理员强制执行的列表视图阈值"。为避免此异常并按批次读取列表项,我们可以使用Content Iterator。
ContentIterator提供了很多方法,我们在这里讨论http://msdn.microsoft.com/en-us/library/ee560760%28v=office.14%29.aspx
使用ContentIterator包括14 / ISAPI /中提供的Microsoft.Office.Server.dll,并包含名称空间Microsoft.Office.Server.Utilities。
优势: 获取批处理列表项,减少负载。 如果索引列条件返回的值多于列表视图阈值,则按批处理。正常SPQuery在这种情况下失败。 我们可以随时停止批处理。 坏处: 您不能在SPQuery条件中包含非索引列。
//Run as console application
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.Office.Server.Utilities;
namespace ContentIteratorListItemCollBatch
{
class Sample
{
static int NumberOfBatch = 0, NumberOfItemsRead = 0, NumberOfException = 0;
static void Main(string[] args)
{
using (SPSite site = new SPSite("your site url"))
{
using (SPWeb web = site.OpenWeb())
{
SPList list = web.GetList("Lists/LargeList/AllItems.aspx"); //your list url
ContentIterator ci = new ContentIterator("Reading All Items");
SPQuery qry = new SPQuery();
qry.QueryThrottleMode = SPQueryThrottleOption.Strict; //Ensuring that all users come under List View Threshold. (Including farm admins / box administrators).
qry.RowLimit = 2000; //Number of Items read in a batch. But it should be less than List View Threshold.
qry.Query = qry.Query + ContentIterator.ItemEnumerationOrderByID; //Not Required, Include for faster output.
//Don't use ContentIterator.ItemEnumerationOrderByNVPField, it gets into infinite loop.
ci.ProcessListItems(list, qry, ProcessItemColl, ProcessErrorColl);
Console.WriteLine("\nBatch count: " + NumberOfBatch + "\n\nTotal number of items read: " + NumberOfItemsRead);
Console.ReadLine();
}
}
}
static public bool ProcessErrorColl(SPListItemCollection itemColl, Exception e)
{
// process the error
NumberOfException++;
return true;
}
static public void ProcessItemColl(SPListItemCollection itemColl)
{
//Work on the ListItem Collection object with your own condition
//foreach (SPListItem item in itemColl)
//{
//}
Console.WriteLine("Number of Items Read: " + itemColl.Count);
NumberOfBatch++;
NumberOfItemsRead += itemColl.Count;
}
}
}
我的大型列表包含25,000个项目。你可以从输出中看到,它按批次的2000个项目读取了25,000个项目。
输出
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 1000
Batch count: 13
Total number of items read: 25000
确保满足以下条件。 在where where条件下只允许使用Indexed列。 您应该包含ContentIterator.ItemEnumerationOrderByNVPField。 在下面的代码中,Title是一个索引列。创建自定义列表后,标题将作为索引列。
//作为控制台应用程序运行
使用System; 使用System.Collections.Generic; 使用System.Linq; 使用System.Text; 使用Microsoft.SharePoint; 使用Microsoft.Office.Server.Utilities;
namespace ContentIteratorListItemCollBatch
{
class Sample
{
static int NumberOfBatch = 0, NumberOfItemsRead = 0, NumberOfException = 0;
static void Main(string[] args)
{
using (SPSite site = new SPSite("your site url"))
{
using (SPWeb web = site.OpenWeb())
{
SPList list = web.GetList("Lists/LargeList/AllItems.aspx"); //your list url
ContentIterator ci = new ContentIterator("Reading All Items");
SPQuery qry = new SPQuery();
qry.QueryThrottleMode = SPQueryThrottleOption.Strict; //Ensuring that all users come under List View Threshold. (Including farm admins / box administrators).
qry.RowLimit = 2000; //Number of Items read in a batch. But it should be less than List View Threshold.
qry.Query = @"<Where><Contains><FieldRef Name='Title' /><Value Type='Text'>9</Value></Contains></Where>";
qry.Query = qry.Query + ContentIterator.ItemEnumerationOrderByNVPField;
//Have to include this line.
ci.ProcessListItems(list, qry, ProcessItemColl, ProcessErrorColl);
Console.WriteLine("\nBatch count: " + NumberOfBatch + "\n\nTotal number of items read: " + NumberOfItemsRead);
Console.ReadLine();
}
}
}
static public bool ProcessErrorColl(SPListItemCollection itemColl, Exception e)
{
// process the error
NumberOfException++;
return true;
}
static public void ProcessItemColl(SPListItemCollection itemColl)
{
//Work on the ListItem Collection object with your own condition
//foreach (SPListItem item in itemColl)
//{
//}
Console.WriteLine("Number of Items Read: " + itemColl.Count);
NumberOfBatch++;
NumberOfItemsRead += itemColl.Count;
}
}
}
在SPQuery中,如果索引字段的读取超过列表视图阈值限制,则它将失败。 ContentIterator通过批处理来处理它。
Output
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 233
Batch count: 5
Total number of items read: 8233
答案 1 :(得分:0)
首先,关于“整个农场”的问题 - 您的服务器场中可以有多个数据库。创建新网站集(由SPSite
对象表示的网站集)时,可以为其存储选择数据库。每个数据库都有自己的AllUserData
表。因此,您可以通过查询锁定的最大范围是此表。当然,如果您的所有站点都位于单个数据库中,则可能会锁定所有站点。
回答第二个问题 - 这很复杂。有些情况下,您不打算加载超过5000行,但计算需要它。并且SharePoint会终止您的查询。 例如,您有一个很大的项目列表。您应用一个返回少量项目的过滤器。有用。现在,您在某些字段上添加“group by” - 繁荣,它不起作用。 另外,例如,默认的“所有项目”视图变得有问题。您可以使用它,因为它返回30个项目块中的项目。但是,如果您想按特定列进行过滤 - 过滤器不起作用,因为它超过了5000的限制。
答案 2 :(得分:0)
当您在网站集中的列表中查询项目时,您有几个选项。
检索数据的最快速度是索引列表并使用搜索返回项目。您可以自定义排名模型并返回前50个项目。不利的一面是数据只会是你最后一次爬行的新鲜事。
使用自定义代码的另一个选项是使用带有SPSiteDataQuery对象的交叉列表查询。
这样您就可以在不同的列表中返回前50个项目。
在查询高于5000限制的大型列表方面,可以通过增加阈值或以管理员身份执行查询来完成,但这些并不是真正推荐的。 You can put indexes on columns如此大的列表访问速度更快。使用对象模型时,您可以执行您喜欢的操作,但您可能希望衡量性能影响。从数据的角度来看,SharePoint中的数据库实际上是一个抽象概念,您应该更多地关注如何以“SharePoint”方式执行此操作,而不是SharePoint本身如何访问基础数据。
答案 3 :(得分:0)
我有一个包含20k记录的列表,阈值设置为200k(MS表示为5k)。 我同时测试了4个用户点击listview页面,返回20 k记录,但每页有30个项目。什么都没有打破。当读取进行时,这个5k限制是否实际锁定了整个列表?如果是这样的话3个用户怎么能同时访问同一个列表视图页呢?
答案 4 :(得分:0)
由于您只返回30行,因此列表视图阈值永远不会被命中。但是如果您尝试应用order by,那么为了执行该orderby,它必须扫描所有20 k记录,尽管只显示30个。因此,在这种情况下,阈值将被命中。