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.
综上所述:
为什么这个简单的连接查询使用子查询会明显加快?
我对MySQL的了解非常有限.但这些是我的想法:
您的表没有索引.然后,连接必须读取整个第二个表,以便比较第一个表的每一行.
子查询一次读取第二个表并创建索引,然后它不需要为第一个表的每一行读取整个第二个表.它只需要检查索引,这要快得多.
要验证我是否正确,请尝试在两个表(CREATE INDEX ...)中为order_number列创建索引,然后再次运行这两个查询.您的第一个查询应该只需不到一秒钟而不是一分钟.