gpt4 book ai didi

mysql - 如何优化prestashop类别随机获取产品

转载 作者:行者123 更新时间:2023-11-29 15:25:33 25 4
gpt4 key购买 nike

这是prestashop 1.7版本类别获取产品查询。如果使用随机,速度很慢,如何优化?

SELECT    cp.id_category,    p.*,    product_shop.*,    stock.out_of_stock,    IFNULL( stock.quantity, 0 ) AS quantity,    IFNULL( product_attribute_shop.id_product_attribute, 0 ) AS id_product_attribute,    product_attribute_shop.minimal_quantity AS product_attribute_minimal_quantity,    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`,    image_shop.`id_image` id_image,    il.`legend` AS legend,    m.`name` AS manufacturer_name,    cl.`name` AS category_default,    DATEDIFF(        product_shop.`date_add`,    DATE_SUB( "2019-11-30 00:00:00", INTERVAL 7 DAY )) > 0 AS new,    product_shop.price AS orderprice FROM    `ps_category_product` cp    LEFT JOIN `ps_product` p ON p.`id_product` = cp.`id_product`    INNER JOIN ps_product_shop product_shop ON ( product_shop.id_product = p.id_product AND product_shop.id_shop = 1 )    LEFT JOIN `ps_product_attribute_shop` product_attribute_shop ON ( p.`id_product` = product_attribute_shop.`id_product` AND product_attribute_shop.`default_on` = 1 AND product_attribute_shop.id_shop = 1 )    LEFT JOIN ps_stock_available stock ON ( stock.id_product = `p`.id_product AND stock.id_product_attribute = 0 AND stock.id_shop = 1 AND stock.id_shop_group = 0 )    LEFT JOIN `ps_category_lang` cl ON ( product_shop.`id_category_default` = cl.`id_category` AND cl.`id_lang` = 11 AND cl.id_shop = 1 )    LEFT JOIN `ps_product_lang` pl ON ( p.`id_product` = pl.`id_product` AND pl.`id_lang` = 11 AND pl.id_shop = 1 )    LEFT JOIN `ps_image_shop` image_shop ON ( image_shop.`id_product` = p.`id_product` AND image_shop.cover = 1 AND image_shop.id_shop = 1 )    LEFT JOIN `ps_image_lang` il ON ( image_shop.`id_image` = il.`id_image` AND il.`id_lang` = 11 )    LEFT JOIN `ps_manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer` WHERE    product_shop.`id_shop` = 1     AND cp.`id_category` = 12     AND product_shop.`active` = 1     AND product_shop.`visibility` IN ( "both", "catalog" ) ORDER BY    RAND()     LIMIT 50

最佳答案

请为每个表提供SHOW CREATE TABLE。与此同时,...

让我们从优化连接开始。

    LEFT JOIN  `ps_product_lang` pl  ON ( p.`id_product` = pl.`id_product`
AND pl.`id_lang` = 11
AND pl.id_shop = 1 )

这需要 INDEX(id_product, id_lang, id_shop) (这些列可以按任何顺序排列。)

不要使用LEFT,除非您确实需要在右侧表中不存在行时将其作为 NULL 获取。特别是,

LEFT JOIN  `ps_product` p

可能会妨碍优化。

    WHERE  product_shop.`id_shop` = 1
AND product_shop.`active` = 1
AND product_shop.`visibility` IN ( "both", "catalog" )

可能会从这些索引中受益

INDEX(id_shop, active, visibility, id_product)
INDEX(id_product, id_shop, active, visibility)

产品类别需求

INDEX(id_category, id_product)   -- in this order.

一般来说,多对多映射表需要遵循此处的提示:http://mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table

该查询存在“爆炸-内爆”综合症。这是它首先执行JOIN的地方,收集大量数据,然后由于LIMIT 10而丢弃其中的大部分数据。或许可以通过彻底改变查询来解决这个问题。一般 ID 是从派生表开始,该表获取所需的 10 行,然后进入另一个表以获得所需的其余列。这种“到达”只需要发生 10 次,而不是当前需要的 JOIN 次数。

SELECT ...
FROM ( SELECT <<primary key columns from cp, p, and product_shop>>
FROM cp
JOIN p ON ...
JOIN product_shop ON ...
ORDER BY RAND()
LIMIT 10 ) AS x
JOIN <<p, product_shop ON their PKs>> -- to get p.*, product_shop.*>>
[LEFT] JOIN << each of the other tables>> -- to get the other tables

您应该首先测试子查询(“派生”表),以验证它明显比原始查询快。

关于mysql - 如何优化prestashop类别随机获取产品,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59113742/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com