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

Как лучше оптимизировать выборку из ИБ

00 голосов
3
Добрый день.

Подскажите, как лучше оптимизировать выборку из ИБ в котором около 50 тыс записей. Фильтрует очень медленно, а с ростом базы будет еще хуже.

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

Пример:
Есть список товаров, для каждой записи товара указан код продавца (свойство в ИБ). Подробная информация о продавце хранится в отдельном ИБ.

При выводе списка из 10 товаров, нужно 10 раз обратиться к ИБ продавцов, взять оттуда инфо и вывести это все единым списком.

Сейчас используется CIBlockElement::GetByID - в процессе вывода списка товаров.

Но это очень медленно!

Идеи:
Создать отдельный компонент, который будет работать аналогично CIBlockElement::GetByID, но кешировать такие обращения.
Это снизит нагрузку на базу, т.к. продавцы меняются не часто.

Вариант 2, записывать в ИБ с товарами текстовые значения о продавце в момент добавления товара, а затем просто выводить как свойство. Но это сложно с точки зрения реализации (очень много связей, придется контролировать все изменения продавца, обновлять информацию в товаре и тп.)


Вопрос, как это лучше реализовать, наверняка сталкивались с подобным?
спросил 06 Март, 14 от Priory (100 баллов)

3 Ответы

00 голосов
Мой метод.

Допустим имеется у нас инфоблок с предложениями продавцов. В каждом предложении у нас есть поле с привязкой к продавцу. Продавец - это запись в другом инфоблоке. Делать обращение к продавцам при обработке каждого предложения - затратно и нелогично.

Делаем следующим образом. Сначала перебираем все предложения и записываем все возможные значения продавцов (ID записи в инфоблоке продавцов) в отдельный массив при этом ключами (!). Т.е. обрабатывая запись мы получили ID продавца = 100, делаем ключ в массив $arSellers[100] = 1. В итоге получаем массив продавцов, где ключи - ID продавцов, а значения везде = 1. Массив имеет вид:
Код
array(
1=>1,
2=>1,
3=>1,
4=>1,
...
);


Теперь делаем выборку вида
Код
CIBlockElement::GetList(array(), array('ID'=>array_keys($arSellers)));

В ходе этой обработки, допустим, мы можем $arSellers[100] заменить на значения элемента с ID = 100. Получим некий справочник продавцов.

Ну и далее вы этот справочник можете использовать как душе угодно - вставить в выборку предложений, вывести в шаблоне название и ссылку на продавца. Тут по сути всего 2 запроса (хотя на практике может быть чуть больше, допустим 4 или 5). Ну и разумеется, лучше всё это хозяйство кэшировать.
ответил 16 Авг, 14 от bazzet (620 баллов)
00 голосов
Спасибо, заменили на предложенный вами механизм, надеюсь получится ускорить.
Пока, к сожалению, не сильно заметно, т.к. выбирается большой объем данных.

Какие еще могут быть варианты оптимизации для подобных структур данных?
ответил 21 Дек, 14 от Priory (100 баллов)
00 голосов
Во-первых, можно не перебирать все для получения ID продавцов, а заполнять массив по мере получения информации о товарах. Во-вторых, не пытались оптимизировать запросы в GetList? Приведите пример кода - возможно, сумеем помочь. Ну и как вариант, попробуйте сменить структуру инфоблоков.
ответил 11 Апр, 15 от Pomnep (13,960 баллов)

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

0 голосов
10 ответов
спросил 12 Фев, 13 от Yoghurt (200 баллов)
0 голосов
1 ответ
спросил 09 Сен, 21 от root (25,590 баллов)
0 голосов
3 ответов
спросил 05 Март, 14 от Snezhka (2,240 баллов)
0 голосов
2 ответов
спросил 14 Фев, 14 от Lollipopk (660 баллов)