我在执行MySql查询时遇到一个很大的问题,这个问题非常慢。太慢了。不能用!
阅读1000种产品的价格,它需要超过20秒!
$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
");编辑:
按照Mr.Alvaro的建议,我已经更改了SELECT *,它的值选择列表效率更高,执行时间从20秒下降到14秒。还是太慢..。
端编辑
每个产品可以有不同的价格,所以我使用(选择最大.)接受最近(但不是未来)的价格。也许这个功能能减缓一切?在你看来有更好的解决办法吗?
考虑相同的查询,如果没有连接和价格,它只需0.2秒。所以我确信问题就在代码的那一部分。
$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
");我还考虑了这样一个事实,即它可能依赖于服务器的能力,但我倾向于排除它,因为第二个查询(没有价格)是可以接受的速度。
价格表如下
+----------------+-------------+
| price_id | int(3) |
| price_brand | varchar(5) |
| price_code | varchar(50) |
| price_value | float(10,2) |
| price_validity | date |
| price_language | varchar(2) |
+----------------+-------------+发布于 2017-12-06 12:50:03
解决了
问题出在最后一次加入价格表。按照建议,我成功地执行了SELECT MAX (.)另外,它只需0.1秒即可执行。
因此,我决定在没有价格的情况下运行主查询,然后,在then中获取数组,然后运行第二个查询来获取每个产品的价格!这个工作非常完美,我的页面已经从20秒下降到了几十秒。
所以,代码会变成这样:
$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
");然后..。
while ($array = mysqli_fetch_array($dati)) {
$code = $array['product_code'];
$dati_prices = mysqli_query($mysqli_connect, "
SELECT *
FROM $tb_prices
WHERE $tb_prices.price_brand = '$brand' AND $tb_prices.price_code = '$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_prices.price_code = '$code'
)
GROUP BY $tb_prices.price_code
") ;
}也许不是最好和优雅的解决方案,但对我来说,工作相当好!
发布于 2017-12-04 10:24:36
也许是因为你在使用SELECT *,这就是所谓的不良实践。检查堆栈溢出中的此问题。
在那里,米奇·麦子写道:
您应该指定一个显式列列表。SELECT *将带来比创建更多IO和网络流量所需的更多列,但更重要的是,即使存在非群集覆盖索引(在Server上),也可能需要额外的查找。区块报价
https://stackoverflow.com/questions/47631051
复制相似问题