Всем доброго времени суток. Столкнулся со следующей проблемой: при добавлении на сайт большого количества купонов на скидки (в моем случае их 2 000 000), все компоненты каталога (catalog.section, catalog.element и т.д.) начинают дико тормозить (в среднем 4 - 10 секунд на компонент). Конечно большая часть хитов приходится на кеш, но посещаемость большая и условий вывода цен множество (разные города, склады), в связи с этим большое количество пользователей (Средняя посещаемость 10 000 уников в сутки) попадает на не закешированные компоненты.
В ходе детального анализа было установлено сто нагрузку дает CIBlockPriceTools::SetCatalogDiscountCache(Array ( ) ), а точнее CIBlockPriceTools::SetCatalogDiscountCache(Array ( ) ) вызываемый в нем.
Собственно кусок скрипта в файле /bitrix/modules/iblock/classes/general/comp_pricetools.php
Получается, что для формирования корректной цены товара, компонент каждый раз перебирает таблицу b_catalog_discount_coupon на предмет присутствия в ней купонов по определенной скидке и в случае если купон есть скидка к товару не применяется. Но это же 2 000 000 строк перебираемых каждый раз.
Поддержка битрикса на эту ситуацию ответила, что "Есть сторонние организации-партнеры которые могут помочь Вам оптимизировать код вашего сайта и снизить нагрузку, к ним и обращайтесь, а мы здесь ни причем", мои аргументы про то что я говорю о функциях вызываемых из ядра системы результат не возымели, мне было предложено копать в сторону индексов и вообще их этим не беспокоить. Собственно работа с индексами так же не принесла успехов. Так как в таблице физически не может быть записей с пустым полем COUPON, то скрипт так и продолжает перебирать все строки.
Уважаемые форумчане, к Вам запрос! Кто сталкивался с подобной проблемой и как ее решили? Или же мысли в целом о вариантах устранения этой проблемы?
В ходе детального анализа было установлено сто нагрузку дает CIBlockPriceTools::SetCatalogDiscountCache(Array ( ) ), а точнее CIBlockPriceTools::SetCatalogDiscountCache(Array ( ) ) вызываемый в нем.
Собственно кусок скрипта в файле /bitrix/modules/iblock/classes/general/comp_pricetools.php
Код |
---|
$arSelect = array( 'ID', 'TYPE', 'SITE_ID', 'ACTIVE', 'ACTIVE_FROM', 'ACTIVE_TO', 'RENEWAL', 'NAME', 'SORT', 'MAX_DISCOUNT', 'VALUE_TYPE', 'VALUE', 'CURRENCY', 'PRIORITY', 'LAST_DISCOUNT', 'COUPON', 'COUPON_ONE_TIME', 'COUPON_ACTIVE', 'UNPACK', 'CONDITIONS' ); $strDate = date($DB->DateFormatToPHP(CSite::GetDateFormat('FULL'))); $discountRows = array_chunk($arRest['DISCOUNTS'], 500); foreach ($discountRows as &$row) { $arFilter = array( '@ID' => $row, 'SITE_ID' => SITE_ID, 'TYPE' => DISCOUNT_TYPE_STANDART, 'RENEWAL' => 'N', '+<=ACTIVE_FROM' => $strDate, '+>=ACTIVE_TO' => $strDate, '+COUPON' => array() ); $rsPriceDiscounts = CCatalogDiscount::GetList(array(), $arFilter, false, false, $arSelect); while ($arPriceDiscount = $rsPriceDiscounts->Fetch()) { $arPriceDiscount['ID'] = (int)$arPriceDiscount['ID']; $arResultDiscountList[$arPriceDiscount['ID']] = $arPriceDiscount; } unset($arPriceDiscount, $rsPriceDiscounts, $arFilter); } |
Получается, что для формирования корректной цены товара, компонент каждый раз перебирает таблицу b_catalog_discount_coupon на предмет присутствия в ней купонов по определенной скидке и в случае если купон есть скидка к товару не применяется. Но это же 2 000 000 строк перебираемых каждый раз.
Поддержка битрикса на эту ситуацию ответила, что "Есть сторонние организации-партнеры которые могут помочь Вам оптимизировать код вашего сайта и снизить нагрузку, к ним и обращайтесь, а мы здесь ни причем", мои аргументы про то что я говорю о функциях вызываемых из ядра системы результат не возымели, мне было предложено копать в сторону индексов и вообще их этим не беспокоить. Собственно работа с индексами так же не принесла успехов. Так как в таблице физически не может быть записей с пустым полем COUPON, то скрипт так и продолжает перебирать все строки.
Уважаемые форумчане, к Вам запрос! Кто сталкивался с подобной проблемой и как ее решили? Или же мысли в целом о вариантах устранения этой проблемы?