【发布时间】:2022-11-02 17:20:02
【问题描述】:
我有一个查询将一个表连接到一个子查询,尽管子查询由于 where 条件返回一个空集,但即使我考虑到它所花费的时间,整个查询在连接时仍然比没有它时花费的时间要长得多要运行的子查询。任何想法为什么会发生这种情况?详情如下
询问:
select Address.*
from Address
left join (
select lotNumber, max(jobId) as id
from Address
where jobId is not null
group by lotNumber
) latestJob on latestJob.lotNumber = Address.lotNumber
架构:
CREATE TABLE `Address` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`streetNumber` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`street` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`lotNumber` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`jobId` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_Address_lotNumber` (`lotNumber`)
) ENGINE=InnoDB AUTO_INCREMENT=1032717 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
解释:
+----+-------------+-----------------+------------+-------+-------------------------------+-------------------------------+---------+---------------------------+---------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------------+------------+-------+-------------------------------+-------------------------------+---------+---------------------------+---------+----------+-------------+
| 1 | PRIMARY | Address | NULL | ALL | NULL | NULL | NULL | NULL | 1027850 | 100.00 | NULL |
| 1 | PRIMARY | <derived2> | NULL | ref | <auto_key0> | <auto_key0> | 183 | Address.lotNumber | 10 | 100.00 | NULL |
| 2 | DERIVED | Address | NULL | index | idx_Address_lotNumber | idx_Address_lotNumber | 183 | NULL | 1027850 | 90.00 | Using where |
+----+-------------+-----------------+------------+-------+-------------------------------+-------------------------------+---------+---------------------------+---------+----------+-------------+
目前Address 表有大约1M 条记录,但jobId 对所有这些记录都是空的,因此左连接子查询返回一个空集。
子查询自行运行大约需要 0.07 秒,但整个查询需要大约 2.22 秒。没有子查询的查询大约需要 0.07 秒。似乎当加入一个空集时,整个查询应该只需要 ~0.07 + ~0.07 = ~0.14 秒,那么额外的 2 秒来自哪里?连接操作中似乎发生了一些低效的事情。无论如何要改善这一点?
谢谢
【问题讨论】:
-
运行代码时返回了多少行数据?
-
@FanoFN,我想它大约有 1M 行,因为 OP 提到了
Currently the Address table has about 1M records,并且由于连接条件失败,左连接应该只从左表返回数据。