【发布时间】:2018-01-04 14:27:31
【问题描述】:
我有两张桌子。 order_details 是 100,000 行,outbound 是 10,000 行。
我需要将它们加入一个名为 order_number 的列中,这两个列都是 VARCHAR(50)。 order_number 在出站表中不是唯一的。
CREATE TABLE `outbound` (
`outbound_id` int(12) NOT NULL,
`order_number` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `order_details` (
`order_details_id` int(12) NOT NULL,
`order_number` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
这是我的初始查询,运行时间超过 60 秒:
SELECT o.order_number
FROM outbound o
INNER JOIN order_details od
ON o.order_number = od.order_number
此查询得到相同的结果,运行时间不到一秒:
SELECT o.order_number
FROM outbound o
INNER JOIN
(
SELECT order_number
FROM order_details
) od
ON (o.order_number = od.order_number)
这让我很惊讶,因为通常子查询要慢得多。
运行EXPLAIN(我仍在学习如何理解)表明子查询版本使用derived2 表,它正在使用索引,并且该索引是auto_key0。我不够精明,不知道如何解释这一点以理解为什么这会产生重大影响。
我正在通过命令行运行这些查询。
我正在为 Linux (x86_64) CentOS 运行 MySQL Ver 14.14 Distrib 5.6.35。
总结:
为什么这个简单的连接查询使用子查询明显更快?
【问题讨论】:
-
MySQL 的优化器不好?您是否也与
EXISTS或IN进行了比较?SELECT o.order_number FROM outbound o WHERE EXISTS( SELECT order_number FROM order_details AS od WHERE o.order_number = od.order_number)或SELECT o.order_number FROM outbound o WHERE order_number IN ( SELECT order_number FROM order_details ) -
@dnoeth 第一个查询需要一分钟,第二个查询是即时的。
-
正如我所说,一个体面的优化器应该将所有四个相似处理(事实上,当
order_details.orde_number不是唯一的时,连接可能会得到不同的结果)。 -
@dnoeth order_number 在出站表中不是唯一的。
标签: mysql sql performance subquery