Как уменьшить время выборки bitrix через GetList?

На сайте 1 пользователю на принадлежит 1 категория в инфоблоке, в ней содержатся подписки пользователя. Необходимо сделать выборку пользователей у которых в списке нет подписок с определенными ID.

Я делаю следующим образом:
- Получаю список всех категорий(их примерно 20к) через GetList
-- Перебираю каждую категорию и вытягиваю через GetList все подписки категории (примерно по 5 штук) каждую подписку через if делаю проверяю, если нужные подписка принадлежит нужному ид, отбрасываем ее. Если все ок, получаем емайл пользователя.

Код приведу ниже

Проблема в том что скрипт выполняется более 40 секунд, как мне кажется, это много весьма. Что делать?

Код функции
public static function collectSendList(){
       // Если ID подписки(TYPE) равен одному из этих ид, отбрасываем ее
      $donateList = array(2698, 2699, 2700, 2705, 37155, 41371);

      // Выборка всех всех групп пользователей
      $users_group = \CIBlockSection::GetList(
                        array(), 
                        array(
                            "IBLOCK_ID" => 7,
                            "LEVEL" => "1",
                            "ACTIVE" => "Y"
                            ),
                        false,
                        array("ID")
                    );
       // Перебираем все группы
        while ($group = $users_group->Fetch()) {
            // Выборка подписок определенной группы
            $subs = \CIBlockElement::GetList(
                        array(), 
                        array(
                            "IBLOCK_ID" => 7,
                            "SECTION_ID" => $group['ID'],
                            "ACTIVE" => "Y"
                            ),
                        false,
                        false,
                        array("PROPERTY_TYPE", "PROPERTY_USER")
                    );

            $donator = null;

           // перебор подписок
            while ($sub = $subs->Fetch()){
                $donator = $sub;
                if(!array_search($sub['PROPERTY_TYPE_VALUE'], $donateList)){
                    $donator = null;
                    break;
                }
            }
            if($donator !== null){
                // Получаем емайл пользователя
                $result = \Bitrix\Main\UserTable::getList(array(
                    'select' => array('ID','EMAIL'),
                    'filter' => array('ID' => $donator['PROPERTY_USER_VALUE'])
                ))->Fetch();
                print_r($result);
            }
        }
    }
  • Вопрос задан
  • 608 просмотров
Пригласить эксперта
Ответы на вопрос 2
winer
@winer
занимаюсь разработкой сайтов на 1c-bitrix
Можно сделать в 2 запроса.
1) получаем ID категорий в которых есть не нужные нам подписки
2) Делаем запрос категорий исключая полученные в 1

\Bitrix\Main\Loader::includeModule("iblock");
$donateList = array(2698, 2699, 2700, 2705, 37155, 41371);

$IBLOCK_ID = 7;
$arSelect = Array("IBLOCK_SECTION_ID");
$arFilter = Array(
    "IBLOCK_ID" => $IBLOCK_ID,
    "ACTIVE" => "Y",
    "PROPERTY_TYPE" => $donateList
);

$res = CIBlockElement::GetList(array("IBLOCK_SECTION_ID" => "ASC"), $arFilter, ["IBLOCK_SECTION_ID"], false, $arSelect);
$blackListSections = [];
while ($arItem = $res->Fetch()) {
    $blackListSections[] = $arItem["IBLOCK_SECTION_ID"];
}

$users_group = \CIBlockSection::GetList(
    array(),
    array(
        "IBLOCK_ID" => $IBLOCK_ID,
        "!ID" => $blackListSections
    ),
    false,
    array("ID")
);
//и т.д.
Ответ написан
Комментировать
@LemonFox
stateless mind
Вынести запросы к БД из циклов
$sections = [];
while ($group = $users_group->Fetch()) {
  $sections[] = $group['ID'];
}
...
$subs = \CIBlockElement::GetList(
    array(),
    array(
        "IBLOCK_ID" => 7,
        "SECTION_ID" => $group['ID'],
        "ACTIVE" => "Y",
        "!PROPERTY_TYPE" => $donateList //тут не уверен, нужно потестить, есть ли у bitrix NOT IN
    ),
    false,
    false,
    array("PROPERTY_TYPE", "PROPERTY_USER")
);
...
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы