порылся в структуре базы одного из старых проектов, итого:
чтоб получить все характеристики объекта (одного или несколько), действительно нужнен не 1 запрос, а 2. Второй чтоб подтянуть значения из "мультисправочников", то-есть справочников, из которых товару может быть прикреплено несколько свойств.
например, "Поддерживаемые стандарты сети" - gsm 900, gsm 1800, gsm 1900 (в примере реальных данных ниже, клиент почему-то не сделал такой вариант справочником, но это уже не ко мне вопрос)
Код:
select SQL_NO_CACHE pg.title as `group`, p.title as prop, p.`type` as prop_type, pev.value as prop_list_value, pp.*
from catalog_products_properties as pp
join catalog_properties as p on p.id=pp.id_property
join catalog_properties_groups as pg on pg.id=p.id_property_group
left join catalog_properties_enum_groups as peg on peg.id=p.id_list
left join catalog_properties_enum_values as pev on pev.id=pp.value_numeric and pev.id_enum_category=p.id_list
where pp.id_product=XXX;
96 rows in set (0.01 sec)
+ второй запрос по таблице catalog_properties_enum_values по primary key (второй запрос делается потому, что ссылки на multi-values хранятся в сериализованном виде, здравствуй лень матушка)
+ цикл который из общей портянки формирует более удобоваримую структуру.
Код:
mysql> explain select SQL_NO_CACHE pg.title as `group`, p.title as prop, p.`type` as prop_type, pev.value as prop_list_value, pp.* from catalog_products_properties as pp join catalog_properties as p on p.id=pp.id_property join catalog_properties_groups as pg on pg.id=p.id_property_group left join catalog_properties_enum_groups as peg on peg.id=p.id_list left join catalog_properties_enum_values as pev on pev.id=pp.value_numeric and pev.id_enum_category=p.id_list where pp.id_product=6316177;
+----+-------------+-------+--------+---------------------------+------------+---------+------------------------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------------------+------------+---------+------------------------------------+------+-------------+
| 1 | SIMPLE | pp | ref | id_property,id_product | id_product | 4 | const | 118 | |
| 1 | SIMPLE | p | eq_ref | PRIMARY,id_property_group | PRIMARY | 4 | pp.id_property | 1 | Using where |
| 1 | SIMPLE | pg | eq_ref | PRIMARY | PRIMARY | 4 | p.id_property_group | 1 | Using where |
| 1 | SIMPLE | peg | eq_ref | id | id | 4 | p.id_list | 1 | Using index |
| 1 | SIMPLE | pev | eq_ref | id,id_enum_category | id | 4 | pp.value_numeric | 1 | |
+----+-------------+-------+--------+---------------------------+------------+---------+------------------------------------+------+-------------+
5 rows in set (0.01 sec)
mysql> select count(*) from catalog_products_properties;
+----------+
| count(*) |
+----------+
| 3660261 |
+----------+
mysql> select count(*) from catalog_properties;
+----------+
| count(*) |
+----------+
| 2632 |
+----------+
mysql> select count(*) from catalog_properties_groups;
+----------+
| count(*) |
+----------+
| 296 |
+----------+
mysql> select count(*) from catalog_properties_enum_groups;
+----------+
| count(*) |
+----------+
| 266 |
+----------+
mysql> select count(*) from catalog_properties_enum_values;
+----------+
| count(*) |
+----------+
| 2240 |
+----------+
Ещё раз, я не аггитирую за eav, просто привёл пример личного использования. Во время разработки сего дела mongo ещё не было.