Управление большими списками/библиотеками в SharePoint

В SharePoint 2010 впервые появилось ограничение на количество выбираемых элементов единовременно из списка или библиотеки документов. Ровно такое же ограничение перекочевало в последующие версии SharePoint On-prem и SharePoint Online.

Причина такого ограничения понятна: ограничить нагрузку на систему путем запрета на выполнение ресурсоемких операций. По умолчанию это ограничение равно 5000 элементам для пользователей и 20000 для администраторов/аудиторов.

Как считать

Первое что приходит на ум при взгляде на фразу "не более 5000 элементов" - никакому пользователю никогда и ни при каких обстоятельствах нет необходимости просматривать одновременно такое большое количество элементов. Тем более в представлениях списка есть постраничный выбор и по умолчанию на одной странице выводится всего 30 элементов. Но даже если у вас в представлении количество элементов на странице равно 10, а предел установлен в 10000 (т.е. выборка составляет всего 1% от максимально допустимой) то это не спасает от получения следующего исключения:

Самое важное, что необходимо понимать - механизм расчета, согласно которому запрос данных считается превышающим пороговое значение. Для примера я создал список, содержащий 11К+ записей. Параметры ограничений настроил следующим образом:

  • Пороговое значение - 2000 элементов
  • Предупреждение - 1200 элементов

Размер страницы в представлениях равен 50, без группировки.

Представление списка

Самый простой пример, с которого мы начнем: представление без фильтра и без сортировки. В этом случае превышение порогового значения не будет сколько элементом не добавляй:

Что здесь не так?

В этом случае сообщение об ошибке будет выдано при попытке отсортировать представление:

или отфильтровать его:

В списке много элементов, которые выводятся постранично без фильтрации и сортировки. Но все мы знаем, что при выводе данных постранично обязательно должна быть сортировка. И она есть:

Из этого следует, что мы всегда можем сортировать представление по полю ID (в любом направлении) не зависимо от количестве данных и ограничений на выборку. Если в пример выше добавить сортировку по полю ID или выполнить сортировку на форме просмотра представления, то всё будет работать (только фильтровать по полю ID не получится). Если у вас большой список/библиотека и вам необходимо сортировать по дате создания (выводить новые элементы, документы сверху), то используйте сортировку по полю ID в обратном порядке.

Индексированные поля

Чтобы представление с большим количеством элементов можно было сортировать, то эти поля должны быть добавлены в список индексируемых. В SharePoint 2016 это происходит автоматически, в предыдущих версиях придется делать это вручную. Индекс в SharePoint работает следующим образом:

Для индексируемого поля в таблице dbo.NameValuePair_{COLLATION} создаются записи, содержащие значения поля для каждого элемента списка:

В дальнейшем эти данные используются при выборке данных из списка.

Иногда говорят, что поле ID всегда автоматически индексируемое. Это не так, совсем не так. Поле ID не может быть добавлено в список индексируемых, т.к. значения этого поля всегда уникальны и нет никакого смысла создавать дубликат этих значений.

Таким образом:

Также необходимо помнить о том, что значения в индексе создаются/изменяются/удаляются при соответствующих операциях в списке, что снижает производительность.

Фильтрация

Фильтрация больших списков аналогична сортировке - нельзя фильтровать по неиндексированным полям. Даже если результат запроса всегда пустой:

Обход ограничения

Самый простой способ - увеличить максимальное значение выбираемых элементов в свойствах веб-приложения:

Либо с помощью PowerShell:


$app = Get-SPWebApplication -Identity https://portal.company.ru
$app.MaxItemsPerThrottledOperation = 10000
$app.Update();

Помимо этого можно отключить проверку на превышение лимита для конкретного списка. Через PowerShellб используя свойство SPList.EnableThrottling:


$web = Get-SPWeb http://portal.company.ru
$list = $web.GetList("Lists/MyMegaList")
$list.EnableThrottling = $false
$list.Update();

Последний вариант более предпочтителен, т.к. позволяет контролировать большие списки, явно указывая к каким из них не относится ограничение.

Также можно распределить содержимое списка/библиотеки по папкам.

Виталий Жуков

Виталий Жуков

Техлид, Архитектор, Разработчик, Microsoft MVP. Более 20 лет опыта в области системной интеграции и разработки программного обеспечения. Специализируюсь на проектировании и внедрении масштабируемых высокопроизводительных программных решений в различных отраслях.

Смотрите также