Управлять работой CIBlockElement::GetList

Рейтинг: 1.5505  
Новая
Предложил Карабаев Виктор 30.03.2013 19:18:30

Управлять работой CIBlockElement::GetList

Имеется некая база данных. Имеется следующий код:


$arSel ect2 = Array("ID", "NAME", "PROPERTY_USER", "PROPERTY_ZAKAZ", "PROPERTY_CAT_ID", "PROPERTY_CAT_ARTICUL", "PROPERTY_CAT_MANUF", "PROPERTY_CAT_NAME", "PROPERTY_CAT_SUPPLIER", "PROPERTY_CAT_DATE", "PROPERTY_CAT_PRICE", "PROPERTY_CAT_QUANT";);
$arFilter2 = Array("IBLOCK_ID"=>$IBLOCK, "ACTIVE_DATE"=>"Y", "ACTIVE"=>"Y", "PROPERTY_USER"=>$_REQUEST["uid"], "!PROPERTY_ZAKAZ"=>5, "SECTION_ID"=>$_REQUEST["sid"]);
$res2 = CIBlockElement::GetList(Array(), $arFilter2, false, Array(), $arSelect2);
while($ob2 = $res2->GetNextElement()) {
 $arFields2 = $ob2->GetFields();    
}


На данный момент вот в данном инфоблоке, находится всего два элемента. Вообще в базе, около 4000 элементов, с разными свойствами. Сервер - отдельный физический сервер. Centos6. Веб окружение Битрикс с оптимальными конфигурационными файлами.

Время выполнения кода выше - 33 секунды.

Проблема:

SELECT COUNT('x') as C
FR OM
b_iblock B
INNER JOIN b_lang L ON B.LID=L.LID
INNER JOIN b_iblock_element BE ON BE.IBLOCK_ID = B.ID
INNER JOIN b_iblock_property FP0 ON FP0.IBLOCK_ID = B.ID AND FP0.CODE='USER'
LEFT JOIN b_iblock_property FP1 ON FP1.IBLOCK_ID = B.ID AND FP1.CODE='ZAKAZ'
LEFT JOIN b_iblock_property FP2 ON FP2.IBLOCK_ID = B.ID AND FP2.CODE='CAT_ID'
LEFT JOIN b_iblock_property FP3 ON FP3.IBLOCK_ID = B.ID AND FP3.CODE='CAT_ARTICUL'
LEFT JOIN b_iblock_property FP4 ON FP4.IBLOCK_ID = B.ID AND FP4.CODE='CAT_MANUF'
LEFT JOIN b_iblock_property FP5 ON FP5.IBLOCK_ID = B.ID AND FP5.CODE='CAT_NAME'
LEFT JOIN b_iblock_property FP6 ON FP6.IBLOCK_ID = B.ID AND FP6.CODE='CAT_SUPPLIER'
LEFT JOIN b_iblock_property FP7 ON FP7.IBLOCK_ID = B.ID AND FP7.CODE='CAT_DATE'
LEFT JOIN b_iblock_property FP8 ON FP8.IBLOCK_ID = B.ID AND FP8.CODE='CAT_PRICE'
LEFT JOIN b_iblock_property FP9 ON FP9.IBLOCK_ID = B.ID AND FP9.CODE='CAT_QUANT'
INNER JOIN b_iblock_element_property FPV0 ON FPV0.IBLOCK_PROPERTY_ID = FP0.ID AND FPV0.IBLOCK_ELEMENT_ID = BE.ID
LEFT JOIN b_iblock_element_property FPV1 ON FPV1.IBLOCK_PROPERTY_ID = FP1.ID AND FPV1.IBLOCK_ELEMENT_ID = BE.ID
LEFT JOIN b_iblock_element_property FPV2 ON FPV2.IBLOCK_PROPERTY_ID = FP2.ID AND FPV2.IBLOCK_ELEMENT_ID = BE.ID
LEFT JOIN b_iblock_element_property FPV3 ON FPV3.IBLOCK_PROPERTY_ID = FP3.ID AND FPV3.IBLOCK_ELEMENT_ID = BE.ID
LEFT JOIN b_iblock_element_property FPV4 ON FPV4.IBLOCK_PROPERTY_ID = FP4.ID AND FPV4.IBLOCK_ELEMENT_ID = BE.ID
LEFT JOIN b_iblock_element_property FPV5 ON FPV5.IBLOCK_PROPERTY_ID = FP5.ID AND FPV5.IBLOCK_ELEMENT_ID = BE.ID
LEFT JOIN b_iblock_element_property FPV6 ON FPV6.IBLOCK_PROPERTY_ID = FP6.ID AND FPV6.IBLOCK_ELEMENT_ID = BE.ID
LEFT JOIN b_iblock_element_property FPV7 ON FPV7.IBLOCK_PROPERTY_ID = FP7.ID AND FPV7.IBLOCK_ELEMENT_ID = BE.ID
LEFT JOIN b_iblock_element_property FPV8 ON FPV8.IBLOCK_PROPERTY_ID = FP8.ID AND FPV8.IBLOCK_ELEMENT_ID = BE.ID
LEFT JOIN b_iblock_element_property FPV9 ON FPV9.IBLOCK_PROPERTY_ID = FP9.ID AND FPV9.IBLOCK_ELEMENT_ID = BE.ID
LEFT JOIN b_iblock_property_enum FPEN0 ON FPEN0.PROPERTY_ID = FPV1.IBLOCK_PROPERTY_ID AND FPV1.VALUE_ENUM = FPEN0.ID
INNER JOIN ( SELECT DISTINCT BSE.IBLOCK_ELEMENT_ID
FR OM
b_iblock_section_element BSE
INNER JOIN b_iblock_section BS ON BSE.IBLOCK_SECTION_ID = BS.ID
WHERE
((BS.ID IN (3700))) ) BES ON BES.IBLOCK_ELEMENT_ID = BE.ID
WH ERE
1=1 AND ( ((((BE.IBLOCK_ID = '12')))) AND (((BE.ACTIVE_TO >= now() OR BE.ACTIVE_TO IS NULL) AND (BE.ACTIVE_FROM <= now() OR BE.ACTIVE_FROM IS NULL))) AND ((((BE.ACTIVE='Y')))) AND ((((FPV0.VALUE LIKE '1')))) AND ((( FPV1.VALUE_ENUM IS NULL OR NOT (FPV1.VALUE_ENUM = '5')))) ) AND (((BE.WF_STATUS_ID=1 AND BE.WF_PARENT_ELEMENT_ID IS NULL)))    


Этот запрос занимает всё время. И результат его работы - просто подсчет количества элементов...

ЗАЧЕМ????

Мне НЕ нужно в данном случае считать элементы! ПОЧЕМУ нельзя или обойтись без этого запроса совсем, или сделать некую переменную через которую управлять подсчетом??? Передана функции переменная - посчитали. Нет - ничего не считаем.

Проблема имеет общий характер.

Обобщая это звучит так:

Если вы используете функцию CIBlockElement::GetList, вам нужно сделать выборку из инфоблока с большим количеством свойств, и нужно выбрать эти свойства, производительность падает фатально. И чем больше размер у вас бд, тем хуже и фатальней результат.