Как правильно выгружать большие объемы данных
Часто встает задача импорта каких либо сущностей с портала посредством rest. При этом при большом количестве сущностей прямой подход к задаче, с установкой фильтра и передачей в каждый следующий запрос start = start+50
, не оптимальный.
Так как, при использование start >= 0
на каждый запрос выполняется еще и запрос подсчета количества элементов удовлетворяющих фильтру. Что при большом количестве элементов, попадающих в него, или при сложной фильтрации работает медленно.
Поэтому в случае если вам не нужно количество элементов ( например вам нужно просто 10 последних записей ) или вы делаете импорт всех записей по фильтру, передавайте start = -1
.
Данный параметр отключит выполнение запроса подсчета количества элементов и сильно ускорит выборку.
Для выполнения импорта, при этом необходимо будет отсортировать записи по ID и добавить в фильтр условие ID > значения последнего элемента. И с каждым шагом увеличивать его значение. Значение же последнего элемента брать из последнего значения полученного результата.
Условием остановки импорта будет пустой ответ, или то, что в ответе элементов меньше 50.
Ниже приведен пример кода и сравнение времени выполнения с классическим подходом. Так при 2 387 743 лидах, с одинаковыми правами и фильтром, время выполнения уменьшилось с 49.9 секунд до 0,097 секунд.
Пример
$tokenID = 'XXXXXXXXXXXXXXXXXXXXX'; $host = 'XXXX.bitrix24.ru'; $user = 1; /** * Начинаем с нуля или с какого то предыдущего шага */ $leadID = 0; $finish = false; while (!$finish) { /** * Выполняем пока не заберем все данные, в этом случае не стоит забывать и про задержку между хитами. * Либо каждый раз выбираем только 50, начиная с того элемента, на котором остановилась прошлая итерация */ $http = new \Bitrix\Main\Web\HttpClient(); $http->setTimeout(5); $http->setStreamTimeout(50); $json = $http->post( 'https://'.$host.'/rest/'.$user.'/'.$tokenID.'/crm.lead.list/', [ 'order' => ['ID' => 'ASC'], 'filter' => ['>ID' => $leadID], 'select' => ['ID', 'TITLE', 'DATE_CREATE'], 'start' => -1 ] ); $result = \Bitrix\Main\Web\Json::decode($json); if (count($result['result']) > 0) { foreach ($result['result'] as $lead) { $leadID = $lead['ID']; } // Do something } else { $finish = true; } } /* //Результаты выполнения rest запроса с использованием count. Array ( [result] => Array ( [0] => Array() [1] => Array() ..... [49] => Array() ) [next] => 50 [total] => 2387743 [time] => Array ( [start] => 1581607213.4833 [finish] => 1581607263.3997 [duration] => 49.916450023651 [processing] => 49.899916887283 [date_start] => 2020-02-13T18:20:13+03:00 [date_finish] => 2020-02-13T18:21:03+03:00 ) ) //Результаты выполнения rest запроса без использования count. Array ( [result] => Array ( [0] => Array() [1] => Array() ..... [1] => Array() ) [total] => 0 [time] => Array ( [start] => 1581609136.3857 [finish] => 1581609136.4835 [duration] => 0.097883939743042 [processing] => 0.068500995635986 [date_start] => 2020-02-13T18:52:16+03:00 [date_finish] => 2020-02-13T18:52:16+03:00 ) ) */
Сообщение не промодерировано, возможны ошибки и неточности.
|
Попытка установки ">id" у Смарт процесса
"error_description": "Mysql query error: (1064) You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')\nAND `crm_items_20`.`ID` IN (SELECT P.ENTITY_ID FROM b_crm_entity_perms P WHERE' at line 12" |
Сообщение не промодерировано, возможны ошибки и неточности.
|
||
| ||
Сообщение не промодерировано, возможны ошибки и неточности.
|
Не работает для department и для productsection
|
Сообщение не промодерировано, возможны ошибки и неточности.
|
и как делать сортировку всей выборки при таком способе? например по имени лида
|
Сообщение не промодерировано, возможны ошибки и неточности.
|
и как делать сортировку всей выборки при таком способе? например по имени лида
|
Сообщение не промодерировано, возможны ошибки и неточности.
|
и как делать сортировку всей выборки при таком способе? например по имени лида
|
Сообщение не промодерировано, возможны ошибки и неточности.
|
Вот тут можно прочитать про исследования разных стратегий ускорения получения больших объемов данных по REST API:
|
Пользовательские комментарии
Мы будем рады, если разработчики добавят свои комментарии по практическому использованию методов системы.Для этого нужно всего лишь авторизоваться на сайте
Но помните, что Пользовательские комментарии, несмотря на модерацию, не являются официальной документацией. Ответственность за их использование несет сам пользователь.
Также Пользовательские комментарии не являются местом для обсуждения функционала. По подобным вопросам обращайтесь на форумы.