работа SS5 при большом количестве SKU основанных на характеристиках

у меня есть база в которой 48000 SKU так вот если у товара было 2 характеристики для выбора все работает, а как только у товара появлялась 3 характеристики то товар в корзину не клался. после анализа выяснилось что функция getSkuByFeatures создавала SQL запрос который должен был обработать 48000 в кубе записей.. после чего база данных требовала больше ресурсов :(
так вот я изменил эту функцию чтобы она не требовала много ресурсов
было :

$sql = "SELECT t0.sku_id FROM ".$this->table." t0 ";
for ($i = 1; $i < count($features); $i++) {
$sql .= " JOIN ".$this->table." t".$i." ON t0.sku_id = t".$i.".sku_id";
}
$sql .= " WHERE t0.product_id = ".(int)$product_id." AND t0.sku_id IS NOT NULL";
$i = 0;
foreach ($features as $f => $v) {
$sql .= " AND t".$i.".feature_id = ".(int)$f." AND t".$i.".feature_value_id = ".$v;
$i++;
}

$sql .= " LIMIT 1";
return $this->query($sql)->fetchField();

стало

$sql = "SELECT t0.sku_id FROM (SELECT * FROM ".$this->table." WHERE `product_id`=".(int)$product_id.") t0 ";
for ($i = 1; $i < count($features); $i++) {
$sql .= " JOIN (SELECT * FROM ".$this->table." WHERE `product_id`=".(int)$product_id." ) t".$i." ON t0.sku_id = t".$i.".sku_id";
}
$sql .= " WHERE t0.sku_id IS NOT NULL";
$i = 0;
foreach ($features as $f => $v) {
$sql .= " AND t".$i.".feature_id = ".(int)$f." AND t".$i.".feature_value_id = ".$v;
$i++;
}
$sql .= " LIMIT 1";
return $this->query($sql)->fetchField();

надеюсь такую оптимизацию проведут разработчики и мои изменения не затрутся при очередном обновлении.

3 ответа

  • 0
    вот в этом файле.
    \wa-apps\shop\lib\model\shopProductFeatures.model.php
  • 0
    Sm 24 октября 2013 09:46 #
    собственно сюда тоже отпишу: помогает, но глюк с фильтром сохраняется, те если в фильтре указать скажем три параметра для поиска выдает ошибку - Query Error Query: SELECT p.*,p.id FROM shop_product p JOIN shop_product_features pf1 ON p.id = pf1.product_id AND pf1.feature_id = 49 JOIN shop_product_features pf2 ON p.id = pf2.product_id AND pf2.feature_id = 33 JOIN shop_product_features pf3 ON p.id = pf3.product_id AND pf3.feature_id = 32 JOIN shop_product_features pf4 ON p.id = pf4.product_id AND pf4.feature_id = 43 JOIN shop_product_features pf5 ON p.id = pf5.product_id AND pf5.feature_id = 40 JOIN shop_category_products cp1 ON p.id = cp1.product_id WHERE pf1.feature_value_id IN (152) AND pf2.feature_value_id IN (104) AND pf3.feature_value_id IN (98) AND pf4.feature_value_id IN (140) AND pf5.feature_value_id IN (1) AND p.type_id IN (5) AND p.status = 1 AND cp1.category_id IN(56) GROUP BY p.id ORDER BY cp1.sort ASC LIMIT 30 Error: 1104 Message: The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET MAX_JOIN_SIZE=# if the SELECT is okay

    где еще поправить запросы, которые за фильтр отвечают? Потому что если ставить SQL_BIG_SELECTS. то весь сайт будет висеть, пока он обрабатывает этот запрос.
  • 0
    Леонид Вакуленко Webasyst 24 октября 2013 10:04 #
    В таблице shop_product_features не хватает нужного индекса. Он будет добавлен в следующем патче Магазина, или вы можете добавить его вручную, не дожидаясь:

    ALTER TABLE shop_product_features ADD INDEX `sku` (`sku_id`, `feature_id`, `feature_value_id`);

Добавить ответ

Чтобы добавить комментарий, зарегистрируйтесь или войдите