I have a big problem with the execution of a MySql query that is very slow.. too slow... unusable!
To read 1000 products with their prices it takes more than 20 seconds!!!
$dati = mysqli_query($mysqli_connect, "
SELECT *
FROM $tb_products
LEFT JOIN $tb_categories ON $tb_products.product_category = $tb_categories.category_id_master
LEFT JOIN $tb_subcategories ON $tb_products.product_subcategory = $tb_subcategories.subcategory_id_master
LEFT JOIN $tb_logos ON $tb_products.product_logo = $tb_logos.logo_id_master
LEFT JOIN $tb_prices ON (
$tb_products.product_brand = $tb_prices.price_brand
AND $tb_products.product_code = $tb_prices.price_code
AND $tb_prices.price_validity = (
SELECT MAX($tb_prices.price_validity)
FROM $tb_prices
WHERE $tb_prices.price_validity<=DATE_ADD(CURDATE(), INTERVAL +0 DAY)
AND $tb_products.product_code = $tb_prices.price_code
)
)
WHERE $tb_products.product_language='$activeLanguage' AND $tb_products.product_category!=0
GROUP BY $tb_products.product_code
ORDER BY $tb_products.product_brand, $tb_categories.category_rank, $tb_subcategories.subcategory_rank, $tb_products.product_subcategory, $tb_products.product_rank
");
EDIT:
I've changed, as suggested from Mr.Alvaro, the SELECT * with a more efficient SELECT [list of values] and the execution time dropped from 20 seconds to 14 seconds. Still too slow...
END EDIT
Each product can have different prices, so I use the (select max...) to take the most recent (but not future) price. Maybe is this function that slow down everything? Are there better solutions in your opinion?
Consider that the same query without the join with the prices it takes only 0.2 seconds. So I'm convinced that the problem is all in that part of the code.
$dati = mysqli_query($mysqli_connect, "
SELECT *
FROM $tb_products
LEFT JOIN $tb_categories ON $tb_products.product_category = $tb_categories.category_id_master
LEFT JOIN $tb_subcategories ON $tb_products.product_subcategory = $tb_subcategories.subcategory_id_master
LEFT JOIN $tb_logos ON $tb_products.product_logo = $tb_logos.logo_id_master
WHERE $tb_products.product_language='$activeLanguage' AND $tb_products.product_category!=0
GROUP BY $tb_products.product_code
ORDER BY $tb_products.product_brand, $tb_categories.category_rank, $tb_subcategories.subcategory_rank, $tb_products.product_subcategory, $tb_products.product_rank
");
I also considered the fact that it could depend on the power of the server but I would tend to exclude it because the second query (without prices) is quite acceptable as speed.
The prices table is as following
+----------------+-------------+
| price_id | int(3) |
| price_brand | varchar(5) |
| price_code | varchar(50) |
| price_value | float(10,2) |
| price_validity | date |
| price_language | varchar(2) |
+----------------+-------------+