Answer the question
In order to leave comments, you need to log in
How to fix slow requests when filtering on the site?
Good afternoon!
Please help with a slow request when filtering
. On a page with 4000 products, the filter shows products quickly, but filters are updated 2 more seconds from above (takes from product attributes).
In the slow query logs, this is:
1 0x1FEE9AB6025C7FCB 24.4336 36.3% 19 1.2860 0.19 SELECT oc_product_attribute oc_attribute_description
SELECT pa.product_id, MAX(ad.attribute_id) as attribute_id, MAX(ad.name) as attribute_name, MAX(pa.text) text, COUNT(*) total FROM `oc_product_attribute` pa LEFT JOIN `oc_attribute_description` ad ON ad. attribute_id = pa.attribute_id WHERE pa.product_id IN (4728,4729,2280,2289,2290,2297,2298,2299,2300,4730,2317,2318,2319,2320,2321,2322,2323,2324,2325,2326 /*... omitted 4043 items ...*/) GROUP BY lower(pa.text), a.attribute_id HAVING COUNT(*) > 0\G
Controller code:
/* attributes */
$results = $this->model_journal2_super_filter->getAttributes($data);
foreach ($results as $key => $result) {
$display_mode = Journal2Utils::getProperty($module_data, 'attributes.' . $key, 'on');
if ($display_mode === 'off') {
continue;
}
$values = array();
foreach ($result['values'] as $value) {
$values[] = array(
'text' => rawurlencode(trim($value['text'])),
'name' => trim($value['text']) . ( $show_product_count ? ' (' . $value['total'] . ')' : ''),
'keyword' => $this->keyword($result['attribute_name'] . " " . $value['text'])
);
}
$this->data['attribute'] = array(
'attribute_id' => $result['attribute_id'],
'attribute_name' => $result['attribute_name'],
'display_mode' => $display_mode,
'type' => Journal2Utils::getProperty($module_data, 'attributes_type.' . $key, 'multi'),
'values' => $values,
);
$this->data['count_attr'] = count($this->data['attribute']['values']);
$this->template = 'journal2/module/super_filter_attributes.tpl';
$filter_groups[] = array(
'sort_order' => Journal2Utils::getProperty($module_data, 'sort_orders.a_' . $result['attribute_id']),
'html' => $this->render()
);
}
public function getAttributes($data = array()){
if(isset($data['attributes']) && !empty($data['attributes'])) {
$product_attributes = $this->getProductAttributes($data);
foreach ($data['attributes'] as $attribute_id => $value) {
foreach($product_attributes as $key => $attribute) {
if($key == $attribute_id) {
unset($product_attributes[$key]);
}
}
$temp_data = $data;
unset($temp_data['attributes'][$attribute_id]);
foreach($this->getProductAttributes($temp_data) as $key => $attribute){
if($key == $attribute_id) {
$product_attributes[$attribute_id] = $attribute;
}
}
}
$results = $product_attributes;
}else{
$results = $this->getProductAttributes($data);
}
ksort($results);
return $results;
}
private function getProductAttributes($data = array()){
$data['start'] = 0;
$data['limit'] = PHP_INT_MAX;
$products = $this->getProducts($data);
if (count($products) == 0) {
return array();
}
$sql = "SELECT pa.product_id, MAX(ad.attribute_id) as attribute_id, MAX(ad.name) as attribute_name, MAX(pa.text) text, COUNT(*) total FROM `". DB_PREFIX . "product_attribute` pa LEFT JOIN `". DB_PREFIX . "attribute_description` ad ON ad.attribute_id = pa.attribute_id";
$sql .= " WHERE pa.product_id IN (" . implode(",", $products) . ")";
//$sql .= " AND pa.language_id = '" . (int)$this->config->get('config_language_id') . "' AND ad.language_id = '" . (int)$this->config->get('config_language_id') . "'";
$sql .= " GROUP BY lower(pa.text), ad.attribute_id HAVING COUNT(*) > 0";
$query = $this->db->query($sql);
$results = array();
foreach ($query->rows as $row) {
if (!isset($results[$row['attribute_id']])) {
$results[$row['attribute_id']] = array(
'attribute_id' => $row['attribute_id'],
'attribute_name' => $row['attribute_name'],
'values' => array()
);
}
$results[$row['attribute_id']]['values'][] = array(
'text' => $row['text'],
'total' => $row['total'],
);
}
foreach ($results as $attribute_id => &$value) {
usort($value['values'], array('ModelJournal2SuperFilter', 'cmpAttrs'));
}
return $results;
}
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question