You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化Magento2中MySQL左连接查询,提升关联购买模块性能?

Magento2「购买此商品的客户也购买了」查询优化方案

1. 简化冗余计算

原查询中(SUM(main_table.product_id) / main_table.product_id)完全等价于COUNT(*)——因为main_table.product_id被WHERE条件固定为1,替换后可减少不必要的计算开销:

SELECT `sub_table`.`product_id`,
       COUNT(*) AS `frequency`

2. 修正JOIN类型

原查询用LEFT JOIN但WHERE子句加入了sub_table的非空过滤条件,这会自动将左连接转为内连接,直接改为INNER JOIN可避免数据库做无效的左连接逻辑:

FROM `sales_order_item` AS `main_table`
INNER JOIN `sales_order_item` AS `sub_table` 
  ON `main_table`.`order_id` = `sub_table`.`order_id` 
  AND `main_table`.`product_id` != `sub_table`.`product_id`

3. 清理无效SELECT字段

原查询中main_table.product_id固定为1,sub_table.order_id在GROUP BY后无意义(每个分组对应多个订单ID,仅返回随机值),直接移除这两个字段,减少数据传输量。

4. 添加针对性索引

针对sales_order_item表创建以下复合索引,大幅提升查询效率:

  • 快速定位目标商品的所有订单:
    CREATE INDEX idx_sales_order_item_product_order ON sales_order_item (product_id, order_id);
    
  • 快速匹配关联订单并过滤有效商品(实现索引覆盖查询,无需回表):
    CREATE INDEX idx_sales_order_item_order_type_parent ON sales_order_item (order_id, product_type, parent_item_id, product_id);
    

5. 优化后的完整查询

SELECT `sub_table`.`product_id`,
       COUNT(*) AS `frequency`
FROM `sales_order_item` AS `main_table`
INNER JOIN `sales_order_item` AS `sub_table` 
  ON `main_table`.`order_id` = `sub_table`.`order_id` 
  AND `main_table`.`product_id` != `sub_table`.`product_id`
WHERE `main_table`.`product_id` = 1
  AND `sub_table`.`product_type` NOT IN ('configurable', 'bundle')
  AND `sub_table`.`parent_item_id` IS NULL
GROUP BY `sub_table`.`product_id`
ORDER BY `frequency` DESC

额外建议

  • 若数据量极大,可采用预计算:定时离线统计商品关联数据,存储到单独的关联表中,查询时直接读取预计算结果,避免实时关联大表。
  • 利用Magento缓存机制,对相同商品的关联查询结果进行缓存,减少重复计算。

内容的提问来源于stack exchange,提问作者Raahull

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 23:05:32