Всем пытливым умам привет!
Групповая обработка справочников и документов - с одной стороны, часто встречающаяся задача у специалистов 1С. С другой стороны, это та область задач, которой не обучают на курсах, о таких задачах не пишут статьи, не проводят исследования и сравнения по скорости обработки данных.
К слову сказать, 24.01.2024г вышла статья в Зазеркалье 1С - "Оптимизация менеджеров объектов для пакетной обработки". Изменение и новшество Планируется в версии 8.3.26.
К слову сказать, на сегодня у меня стоит платформа 8.3.23. И получается, что каждый специалист 1С решает сейчас вопрос оптимизации групповой обработки по своему.
Первый способ - объектный доступ
Групповую обработку объектов 1С буду описывать на примере групповой обработки документов. Первый способ, которым можно обработать документы, это использовать объектный доступ к документам - метод Выбрать().
Можно задать период и отбор по одному полю - например, как часто это требуется, по организации. В типовых конфигурациях поле Организация в документах обычно имеет признак "Индексировать с дополнительным упорядочиванием". Но это надо проверять каждый раз.
Если у вас более сложный алгоритмический отбор, то заранее вы его не зададите через параметр метода Выбрать() - придется в цикле накладывать проверку и пропускать неподходящие документы.
К слову сказать, если вам нужно отобрать только помеченные на удаление или только проведенные документы, то в цикле вы будете проходить все документы подряд - не помеченные на удаление и не проведенные в том числе. Что сильно замедлит выполнение обработки.
Второй способ - запросная модель
Как раз в этот момент вы приходите ко второму способу групповой обработки документов - пробуете отобрать документы через запрос. Пример группового удаления документов демонстрируется на рисунке.
Этот способ как будто бы быстрее первого способа - не надо проходить все документы, можно сразу отобрать их из СУБД.
Данный способ имеет недостаток - если у вас х32 -разрядная конфигурация, то размер выборки выйдет за ограничения по памяти - возникнет критическая ошибка "Не хватает памяти", работа базы завершится. Также, если у вас х64-разрядная конфигурация, и большое количество документов в полученной выборке, то быстродействие групповой обработки сильно замедлится.
Самым слабым звеном в этом алгоритме станет получение выборки - настолько большой, что это займет очень длительное время. И как отработает ваша СУБД - заранее неизвестно. Возможно, она будет способна вытащить из СУБД большую выборку и предоставить вам ее для обработки в цикле.
При этом пока вы обходите в цикле каждый документ, в памяти будет храниться все та же большая выборка.
Возможно, ваша СУБД не позволит вам получить такую большую выборку, и через какое-то продолжительное время выдаст критическую ошибку, что-то типа "Время ожидания ответа от СУБД...." закончилось...
В общем случае, второй способ обработки документов практичен, и поэтому встречается также часто наравне с первым способом. Для уменьшения количества запрашиваемых данных можно сузить период выборки.
Если запрос отработает быстро, значит дело в количестве запрашиваемых документов. В таком случае придется искать "золотую" середину.
Третий способ - пакетная обработка документов
Вот мы пришли к третьему способу получения данных для дальнейшей обработки в цикле - получать данные из СУБД пакетами.
Сравните код запроса на рисунке ниже.
Вы запрашиваете 1000 документов для дальнейшей обработки.
Чтобы реализовать такой способ получения всех документов за период и дальнейшую обработку документов, вам потребуется:
- или рекурсивно вызывать запрос (точнее получение выборки) и дальнейшую обработку документов;
- или использовать цикл в цикле - последний пример продемонстрирован на рисунке ниже.
Четвертый способ - поиск лучшего пакета
Почему именно 1000 документов (записей) используется в пакете? - Определенного обоснования нет.
Вы можете использовать любое количество пакета, кроме наверное таких малых как 1, 2 или 3 и кроме таких больших как 10 000 и больше.
Я запрограммировал поиск лучшего пакета в процессе обработки документов. Алгоритм (листинг) разбил на две страницы, вторая страница сильно сжата относительно первой страницы - чтобы вместить все строки на скриншот.
Первая выборка получается из запроса с параметром "ПЕРВЫЕ 10", фиксируем время выполнения обработки документов ВремяПакета1. Вторая выборка (вторая итерация) получается из запроса с параметром вдвое большим "ПЕРВЫЕ 20", фиксируем время выполнения обработки документов ВремяПакета2.
Если мы увеличиваем выборку в два раза, то достаточно сравнить удвоенное время выполнения первого пакета с временем выполнения второго пакета.
Если при удвоении количества документов в выборке, время выполнения не увеличивается пропорционально в два раза, значит второй пакет более быстрый.
И так продолжаем удваивать пакет до 10 240 (10х2.. х2.. х2.. х2..10 раз) - в любом случае ограничение на количество документов в пакете, думаю, стоит поставить, чтобы случайно не упереться в ограничение вашей СУБД и не вылететь в критическую ошибку .
Примеры
Примеры работ пакетной обработки документов можно скачать на сайте Инфостарт по ссылкам:
На этом все. Всем добра!
С пользой для клиентов, Рустем