Добро пожаловать на сайт <БагБД>, где вы можете задавать вопросы о программировании и разработке на Битрикс и Битрикс24, и получать быстрые и квалифицированные ответы от профессионалов!

Значения свойств элементов инфоблоков - какой вариант самый оптимальный?

00 голосов
5
Имеется инфоблок, с кучей свойств (около сотни, причем примерно половина - связанные инфоблоки со своими свойствами, которые тоже могут содержать связанные элементы, пока ограничено третьим уровнем).
Инфоблок находится под документооборотом.
Сейчас в инфоблоке порядка 400 записей.

Делаю выборку (оставил только часть, которая относится к теме):
Код
$data = array();
$rsElements = CIBlockElement::GetList($arSort, $arFilter, $arGroup, $arNavParams, $arSelect);
while ($obElement = $rsElements->GetNextElement()) {
   if ($obElement) {
      $arItem = $obElement->GetFields();
   } else {
      $arItem = array();
   }
   $data[$arItem['ID']] = $arItem;
}

Это получаются значения первого уровня... Далее таким-же образом получаются элементы второго и третьего уровней.

При этом система на хорошем сервере уже сильно притормаживает (выборка всех элементов идет более 1 минуты).

Начал смотреть в чем дело... В базу делается очень много запросов.
$obElement->GetFields() - это дополнительные запросы в базу, тоесть для каждого элемента выполняется помимо всего еще как минимум 1 запрос дополнительный, даже с учетом того, что в $arSelect перечислены все поля, которые мне нужны.
Тоесть для каждого свойства делается запрос вида:
Код
SELECT BP.*
FROM
b_iblock_property BP, b_iblock B
WHERE
BP.IBLOCK_ID=B.ID AND B.ID IN (IBLOCK_ID) AND UPPER(BP.CODE)=UPPER('CODE_OF_PROPERTY') 


Попробовал обойтись без $obElement->GetFields(), но тогда возвращается массив с ключами типа 'PROPERTY_{ID}', а не 'PROPERTY_{CODE}', как хотелось-бы, более того, для селектов возвращаются ID значения, а не непосредственно значение. Нет кода так-же если указать 'PROPERTY_*'.

Хотел сделать следующим образом: получить вначале id нужных элементов (применив фильтры и сортировки), а затем одним методом получить сразу все свойства. Но выясняю, что CIBlockElement::GetProperty - которое то, что я хотел, принимает только 1 элемент в качестве параметра, а похожих методов, которым можно скормить сразу несколько элементов - нет.

Какие есть способы стандартными средствами, через стандартное АПИ сократить количество запросов в базу?
спросил 17 Дек, 13 от WarCom (100 баллов)

5 Ответы

00 голосов
Покажите еще хотя бы $arFilter и $arSelect, а лучше все параметры GetList()
ответил 27 Фев, 14 от Delp (7,220 баллов)
00 голосов
Но вообще свойства обычно лучше выбирать так:
$arSelect = array(
...,
PROPERTY_*
);

$rsElements = CIBlockElement::GetList($arSort, $arFilter, $arGroup, $arNavParams, $arSelect);
while($obElement = $rsElements->GetNextElement()) {
$arItem = $obElement->GetFields();
$arItem['PROPERTIES'] = $obElement->GetProperties();
$data[$arItem['ID']] = $arItem;
}
ответил 18 Июнь, 14 от Delp (7,220 баллов)
00 голосов
Цитата
Sergey Leshchenko пишет:
Покажите еще хотя бы $arFilter и $arSelect, а лучше все параметры GetList()


Они, вобщем-то не важны, в раках данного вопроса. $arFilter - у меня для полной выборки:
Код
array(
   "IBLOCK_ID" => IBLOCK_ID,
   "IBLOCK_LID" => SITE_ID,
   "IBLOCK_ACTIVE" => "Y",
   "ACTIVE_DATE" => "Y",
   "ACTIVE" => "Y",
   "CHECK_PERMISSIONS" => "Y",
);


$arSelect:
Код
array(
   "ID",
   "NAME",
   "ACTIVE",
)

плюс все возможные 'PROPERTY_...'

остальное не задано.
ответил 17 Окт, 14 от WarCom (100 баллов)
00 голосов
Цитата
RZVL пишет:
Они, вобщем-то не важны, в раках данного вопроса

Да именно они и важны.

Если не важен контроль при многосайтовости и нет никаких особенностей с распределением прав (все пользователи могут читать), то лучше так:
Код
$arFilter = array( 
   "IBLOCK_ID" => <ID инфоблока>, 
   "ACTIVE" => "Y", 
   "ACTIVE_DATE" => "Y" 
); 


Но главный здесь тормоз $arSelect, попробуйте так:
Код
$arSelect = array( 
   'IBLOCK_ID', 
   'ID', 
   'NAME', 
   'PROPERTY_*'
) 

и саму выборку как описал постом выше, лишние/нужные свойства отбирайте уже в самой выборке простыми условными операторами.
ответил 17 Фев, 15 от Delp (7,220 баллов)
00 голосов
Цитата
Sergey Leshchenko пишет:
GetProperties
Цитата
Sergey Leshchenko пишет:
Но вообще свойства обычно лучше выбирать так:
...

$arItem['PROPERTIES'] = $obElement->GetProperties();


Вот это - еще запросы в базу, и то, что это сделает - в принципе мне не нужно...

И по тестам:

У меня в основном инфоблоке 400 элементов... Выбираю все элементы, в селекте только: ID, PROPERTY_ONE

на странице больше ничего нет. Без $obElement->GetProperties() - 20 запросов, с $obElement->GetProperties() - 791 запрос. Когда ставлю 'PROPERTY_*' - вообще все падает (ошибку пока сказать не смогу - нужно включать дебаг).

Но даже по количеству запросов - эта штука убъет все... А на системе предполагается около 5000 элементов...

Мне кажется, или я ошибаюсь, что для базы - 5000 элементов - это ничто... Тоесть должно обрабатываться не то, что влет, а даже быстрее... А здесь для 400 уже слишком большое число запросов - и это для простой выборки только первого уровня.
ответил 27 Май, 15 от WarCom (100 баллов)

Похожие вопросы

0 голосов
4 ответов
0 голосов
0 ответов
0 голосов
7 ответов
0 голосов
4 ответов