【发布时间】:2019-07-09 21:38:42
【问题描述】:
一个 MySQL 数据库包含两个表:customer 和 custmomer_orders
customer 表包含 8000 万个条目和 80 个字段。其中一些我感兴趣:
- Id (PK, int(10))
- 位置(varchar 255,可为空)。
- Registration_Date(日期时间,可为空)。已编入索引。
customer_orders 表包含 4000 万个条目,并且仅包含 3 个字段:
- Id (PK, int(10))
- Customer_Id(int(10),FK 到客户表)
- Order_Date(日期时间,可为空)
当我运行这样的查询时,它需要 ~800 秒来执行并返回 4000 万个条目:
SELECT o.*
FROM customer_orders o
LEFT JOIN customer c ON (c.Id = o.Customer_Id)
WHERE NOT (ISNULL(c.Location)) AND c.Registration_Date < '2018-01-01 00:00:00';
装有 MySQL 服务器的机器有 32GB 的 RAM,28GB 分配给 MySQL。 MySQL 版本:5.6.39。
MySQL 在有这么多记录的表上执行这么长时间的查询是否正常? 如何提高性能?
更新:
customer_orders 表不包含我们想要存储的任何重要数据。这是最近 10 天内下订单的某种复制表。 我们每天都会运行一个存储过程,该过程会删除事务范围内超过 10 天的订单。
在某个时刻,这个存储过程由于没有优化查询而超时,并且订单数量每天都在增长。 以前的查询还包含 COUNT 方法,我想它超过了超时。
然而,令我惊讶的是,MySQL 最多需要 15 分钟才能在附加条件下获取 40m 条记录。
【问题讨论】:
-
(1) 只选择你真正需要的字段; (2) 该查询似乎没有理由使用 LEFT JOIN 而不是 INNER JOIN,您的 WHERE 条件有效地使其成为 INNER JOIN; (3) 连接中使用的字段以及条件应该被索引的地方。
-
订单比客户少,令人印象深刻
-
没有必要再加入一个您不从中选择列的表。但是,您的 WHERE 子句将您的 LEFT JOIN 呈现为 INNER JOIN,因此您不妨一开始就这样写。
标签: mysql sql join query-optimization query-performance