mysql - 使用 LEFT JOINS 优化 MySql 查询

标签 mysql left-join query-optimization

我正在尝试获取 6 个月或更长时间未订购的客户列表。我在查询中使用了 4 个表

  • 帐户 (account_id)
  • 商店(store_id、account_id)
  • 客户(store_id、customer_id)
  • 订单(order_id、customer_id、store_id)

customer 和orders 表非常大,分别有3M 和26M 行,因此在查询中使用左连接会使查询时间变得非常长。我相信我已经正确索引了我的表

这是我使用过的查询

SELECT cus.customer_id, MAX(o.order_date), cus.store_id, s.account_id, store_name
FROM customers cus 
LEFT JOIN stores s ON s.store_id=cus.store_id  
LEFT JOIN orders o ON o.customer_id=cus.customer_id AND o.store_id=cus.store_id
WHERE account_id=26  AND  
    (SELECT order_id 
        FROM orders o 
        WHERE o.customer_id=cus.customer_id 
        AND  o.store_id=cus.store_id 
        AND o.order_date < CURRENT_DATE() - INTERVAL 6 MONTH 
        ORDER BY order_id DESC LIMIT 0,1) IS NOT NULL 
GROUP BY cus.customer_id, cus.client_id;

我需要获取最后的订单日期,这就是我加入订单表的原因,但是由于客户可以有多个订单,因此它会返回客户的多行,即为什么我使用 group by 子句。

如果有人可以帮助我解决我的疑问。

最佳答案

从这里开始:

SELECT  customer_id, MAX(order_date) AS last_order_date
    FROM  orders
    GROUP BY  customer_id
    HAVING  last_order_date < NOW() - INTERVAL 6 MONTH;

假设为您提供了相关的 customer_ids,然后继续

SELECT ...
    FROM ( that-select-as-a-subquery ) AS old
    JOIN other-tables-as-needed  ON USING(customer_id)

如有必要,加入返回订单以获取更多信息。不要尝试获取该子查询中的其他列。 (这是一个“分组最大值”问题。)

关于mysql - 使用 LEFT JOINS 优化 MySql 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36392410/

相关文章:

sql - 为什么 Oracle 中使用 CASE 进行子选择比 JOIN WITH OR 更快

mysql - 尝试考虑用于存储需要连接的日期范围的最佳数据库模式

query-optimization - SPARQL 查询的优化。 [预计执行时间超过 1500(秒)的限制]

java - 将 getGenerateKeys 传递到下一页

php - 选择抽奖券中奖者

mysql - Django 测试 django.db.utils.ProgrammingError : (1146, "Table ' DB.Table'不存在")

php - 从选择查询中排除变量

mysql - 通过合并的 LEFT JOIN 进行过滤

php - MySQL 表优化

php - mysql innodb db varbinary 的正确索引类型是什么?