php - Prestashop 1.7.6.8 getproducts function slow

I'm facing a weird issue with PS 1.7.6.8 with my custom module.
Let me explain the whole thing before :
- I built a custom module from an existing module for searching car parts by an unique ID called Ktype. This is working perfectly.
- I use the Prestashop Search controller to search products, then return them and build a product listing using Product Assembler and Product Listing Assembler
The search controller gets ids from Make, Model, Year and Device from my module, everything is stored in a database table including : Product ID's, ID Make, ID Model, ID Year, ID Device.
When the make, model, year and device is selected, i build an array from the id_product and store it into the variable : pSQL ($id_products)
Then, to show products, i use this function :
public function getProducts($where, $id_lang, $p, $n, $order_by = null, $order_way = null, $get_total = false, $active = true, $random = false, $random_number_products = 1, $check_access = true, Context $context = null)
{
# validate module
unset($check_access);
if (!$context) {
$context = Context::getContext();
}
$front = true;
if (!in_array($context->controller->controller_type, array('front', 'modulefront'))) {
$front = false;
}
if ($p < 1) {
$p = 1;
}
$id_supplier = (int) Tools::getValue('id_supplier');
$sql = 'SELECT DISTINCT p.id_product, p.*, product_shop.*, pl.`description`, pl.`description_short`, pl.`available_now`,
pl.`available_later`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, m.`name` AS manufacturer_name, cl.`name` AS category_default, product_shop.price AS orderprice
FROM `' . _DB_PREFIX_ . 'category_product` cp
INNER JOIN `' . _DB_PREFIX_ . 'product` p
ON p.`id_product` = cp.`id_product`
' . Shop::addSqlAssociation('product', 'p') . '
LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute` pa
ON (p.`id_product` = pa.`id_product`)
' . Shop::addSqlAssociation('product_attribute', 'pa', false, 'product_attribute_shop.`default_on` = 1') . '
LEFT JOIN `' . _DB_PREFIX_ . 'category_lang` cl
ON (product_shop.`id_category_default` = cl.`id_category`
AND cl.`id_lang` = ' . (int) $id_lang . Shop::addSqlRestrictionOnLang('cl') . ')
LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` pl
ON (p.`id_product` = pl.`id_product`
AND pl.`id_lang` = ' . (int) $id_lang . Shop::addSqlRestrictionOnLang('pl') . ')
LEFT JOIN `' . _DB_PREFIX_ . 'manufacturer` m
ON m.`id_manufacturer` = p.`id_manufacturer`
' . $where . '
'
. (Tools::getValue('filter_cat') ? ' AND cp.id_category='. (int) Tools::getValue('filter_cat') : '');
if (Tools::getValue('order') == 'product.position.asc') {
$orderby = 'cp.position ASC';
}
if (Tools::getValue('order') == 'product.name.asc') {
$orderby = 'pl.name ASC';
}
if (Tools::getValue('order') == 'product.name.desc') {
$orderby = 'pl.name DESC';
}
if (Tools::getValue('order') == 'product.price.asc') {
$orderby = 'product_shop.price ASC';
}
if (Tools::getValue('order') == 'product.price.desc') {
$orderby = 'product_shop.price DESC';
}
$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
foreach ($result AS $row) {
if ($row2 = Product::getProductProperties($id_lang, $row)) {
$products[] = $row2;
}
}
return $products;
}
$where variable = WHERE p.id_product IN (pSQL $id_products)
The weird thing is that, when this SQL query is called :
- I can see through phpMyAdmin that this query takes less than 1 second to complete
- Then, lot of other queries, probably coming from the product controller, are executed next.
In my pSQL($id_products) variable, i can have like 4000 product ids comma separated, and i can see the product controller queries are executed for each product_id, and for each parameter that the front controller need (one query for image, one for quantity, one for category, one for add_date, etc ...) leading to a huge number of queries (average is about 150.000 queries for a single search).
I'm using a VPS with 64 GB RAM, 16 Cores Intel I7, and all indexes are used perfectly.
This query takes approx 15 seconds to finish, which is unusable for a webshop.
I already asked for core developers if they have seen such issue before but i never had any answer about PS support.
Is there any way to avoid those multiple subqueries ?
Does it come from the WHERE IN clause in my SQL query ? As each value is comma separated, maybe the controller understand it as a single product, leading to multiple subqueries for all.
If i use a JOIN instead of WHERE IN clause, may it work ? Or i need to keep the WHERE IN clause for the product controller to work ?.
If someone can help me on this, this is driving me crazy.
Thanks for your help !
Answer
Solution:
For each row you call Product::getProductProperties, which is a heavy functionality.
You should estimate if you need data from that method, and if it is not necessary override getProducts and avoid Product::getProductProperties
On the other hand, 4000 products in a category I think is too much, you should subcategorize.
Share solution ↓
Additional Information:
Link To Answer People are also looking for solutions of the problem: undefined array key php
Didn't find the answer?
Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.
Similar questions
Find the answer in similar questions on our website.
Write quick answer
Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.