Перейти к содержимому

Фасетный индекс - зачем нужен и когда пересобирать

Разбираемся, почему фильтр по свойствам на большом каталоге работает секундами и что именно чинит фасетный индекс.

Решение

Смотрим, включён ли индекс у инфоблока:

$row = \Bitrix\Iblock\IblockTable::getList([
'select' => ['ID', 'NAME', 'PROPERTY_INDEX'],
'filter' => ['=ID' => $iblockId],
])->fetch();
printf("%s: индекс %s\n", $row['NAME'], $row['PROPERTY_INDEX'] ?: 'выключен');
// значения: N - выключен, I - собирается, Y - собран и работает

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

Собираем индекс порциями:

$indexer = new \Bitrix\Iblock\PropertyIndex\Indexer($iblockId);
$indexer->startIndex();
while ($indexer->continueIndex(30)) { /* 30 секунд на порцию */ }
$indexer->endIndex();
// на большом каталоге полный проход идёт часами и ставится по расписанию

Индекс включают у инфоблока и собирают порциями. Запуск из интерфейса на большом каталоге упирается в время выполнения, а порционная сборка доходит до конца при любом объёме.

Пересобираем после массовых изменений:

// после обмена, массовой правки свойств или добавления нового свойства в фильтр
$indexer = new \Bitrix\Iblock\PropertyIndex\Indexer($iblockId);
$indexer->startIndex();
// сборку продолжает задание по расписанию, а не этот же запрос

Новые значения свойств появляются в фильтре только после пересборки. Обмен привёз новый бренд, а фильтр его не показывает - это первая и самая частая причина, и лечится она именно здесь.

Считаем, во что обходится объём:

$cnt = CIBlockElement::GetList([], ['IBLOCK_ID' => $iblockId, 'ACTIVE' => 'Y'], []);
$props = count(CIBlockProperty::GetList([], ['IBLOCK_ID' => $iblockId,
'SMART_FILTER' => 'Y'])->Fetch() ? [1] : []);
printf("элементов %s, свойств в фильтре %s\n", $cnt, $props);
// размер индекса растёт как произведение: элементы на значения свойств

Размер индекса растёт как произведение числа элементов на число значений в фильтре. Двадцать свойств в умном фильтре на большом каталоге дают таблицу, сравнимую с самим каталогом.

В фильтр стоит выносить только те свойства, по которым покупатели действительно ищут. Каждое лишнее увеличивает и время сборки, и объём индекса, а покупателю не даёт ничего.

Пересборку ставят по расписанию: ночью и сразу после обмена данными с учётной. Ручной запуск в рабочее время нагружает базу ровно тогда, когда она нужнее всего покупателям.

Разделы каталога тоже участвуют в фасетном индексе умного фильтра витрины. Перенос товаров между разделами - такое же изменение, как правка свойств, и требует той же пересборки.

Перед сборкой индекса на живом каталоге стоит замерить, сколько она идёт на копии. Час на стенде означает час нагрузки на базу боевого сайта, и знать это лучше заранее, чем в разгар рабочего дня.

Типичные проблемы

Фильтр по свойству работает несколько секунд.

Фасетный индекс у инфоблока выключен, и фильтр соединяет большие таблицы значений. Фасетный индекс у инфоблока включают и затем собирают его небольшими порциями.

Новое значение свойства не появилось в фильтре.

После обмена индекс ни разу не пересобирался и не знает о новых значениях. Пересборку индекса ставят сразу следом за обменом данными с учётной системой.

Сборка индекса не доходит до конца.

Она запущена одним общим запросом и упирается в предел времени выполнения скрипта. Сборку индекса ведут порциями и по расписанию, а не одним общим запросом.

Таблица индекса выросла до размеров каталога.

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

После переноса товаров фильтр показывает старое.

Разделы участвуют в индексе, а сам индекс после переноса не пересобран. Перенос товаров между разделами требует ровно такой же полной пересборки индекса.

Частые вопросы

Когда индекс действительно нужен?

Начиная с нескольких тысяч товаров и нескольких свойств в фильтре. На маленьком каталоге разницы не видно.

Пересобирать целиком или частями?

После обмена достаточно продолжить сборку порциями. Полный проход нужен при смене состава свойств фильтра.

Мешает ли индекс обмену с учётной системой?

Сборка во время обмена нагружает базу вдвойне. Её ставят после обмена, а не одновременно.

Что делать, если индекс не помогает?

Смотреть план запроса: узкое место может быть в другом. Индекс лечит фильтр, а не любую медленную страницу.

Смежное

Первоисточник