Документация для разработчиков
Темная тема

Как правильно выгружать большие объемы данных

Часто встает задача импорта каких либо сущностей с портала посредством 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
      )
)
*/

Пользовательские комментарии

Мы будем рады, если разработчики добавят свои комментарии по практическому использованию методов системы.

Для этого нужно всего лишь авторизоваться на сайте

Но помните, что Пользовательские комментарии, несмотря на модерацию, не являются официальной документацией. Ответственность за их использование несет сам пользователь.

Также Пользовательские комментарии не являются местом для обсуждения функционала. По подобным вопросам обращайтесь на форумы.
© «Битрикс», 2001-2020, «1С-Битрикс», 2020
Наверх