我有两张桌子。 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
表,它使用索引,该索引为{{1} }。我不够精明,不知道如何解释这一点,以了解为什么这会产生重大影响。
我在命令行上运行这些查询。
我正在为Linux(x86_64)CentOS运行MySQL Ver 14.14 Distrib 5.6.35。
总结:
为什么使用子查询可以显着加快这种简单的连接查询?
答案 0 :(得分:7)
我对MySQL的了解非常有限。但这些是我的想法:
您的桌子没有索引。 然后,连接必须读取整个第二个表,以便比较第一个表的每一行。
子查询读取第二个表并创建索引,然后它不需要为第一个表的每一行读取整个第二个表。它只需要检查索引,这要快得多。
要验证我是否正确,请尝试为两个表中的order_number列创建索引(CREATE INDEX ...),然后再次运行这两个查询。您的第一个查询应该只需不到一秒钟而不是一分钟。