首页 文章

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

提问于
浏览
7

我有两张 table . 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 .

综上所述:

Why is this simple join query significantly quicker with a sub-query?

1 回答

  • 6

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

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

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

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

相关问题