为什么这个简单的连接查询使用子查询会明显加快?

Goo*_*ose 8 mysql sql performance subquery

我有两张桌子.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;
Run Code Online (Sandbox Code Playgroud)

这是我的初始查询,运行时间超过60秒:

SELECT o.order_number
FROM outbound o
INNER JOIN order_details od
    ON o.order_number = od.order_number
Run Code Online (Sandbox Code Playgroud)

此查询获得相同的结果,运行时间不到一秒:

SELECT o.order_number
FROM outbound o
INNER JOIN
(
    SELECT order_number
    FROM order_details
) od
ON (o.order_number = od.order_number)
Run Code Online (Sandbox Code Playgroud)

这对我来说是令人惊讶的,因为通常子查询要慢得多.

运行EXPLAIN(我还在学习如何理解)显示子查询版本使用derived2表,它使用索引,而索引是auto_key0.我不够精明,不知道如何解释这一点,以了解为什么这会产生重大影响.

我在命令行上运行这些查询.

我正在为Linux(x86_64)CentOS运行MySQL Ver 14.14 Distrib 5.6.35.

综上所述:

为什么这个简单的连接查询使用子查询会明显加快?

Egl*_*Egl 7

我对MySQL的了解非常有限.但这些是我的想法:

您的表没有索引.然后,连接必须读取整个第二个表,以便比较第一个表的每一行.

子查询一次读取第二个表并创建索引,然后它不需要为第一个表的每一行读取整个第二个表.它只需要检查索引,这要快得多.

要验证我是否正确,请尝试在两个表(CREATE INDEX ...)中为order_number列创建索引,然后再次运行这两个查询.您的第一个查询应该只需不到一秒钟而不是一分钟.