2

进一步研究这个问题,我在《高性能 MySQL》(第 219 页)一书中发现了以下内容:

... MySQL 对 IN 列表中的值进行排序,并使用快速二进制搜索来查看值是否在列表中。

它认为这种方法是最优的,以列表的大小来衡量,O(logN)并且它是一种非常好的方法(而不是例如转换为一系列OR语句)。
但是似乎忽略了列表的排序是O(NlogN)这样的结果比做一系列的更OR糟糕O(N)
我在这里有什么误解?
需要明确的是,这是针对列表是来自另一个的巨大结果集的情况SELECT

4

1 回答 1

5

首先,这个语句对于in子查询是不正确的。为此,要么为数据中的每一行运行子查询(5.6 MySQL 之前),要么使用连接优化。

其次,在计算列表的顺序时会发生两件事in。您的两个陈述中都隐含“对于正在处理的每一行”。因此,如果正在处理 R 行,那么实际语句是O(R * logN)O(R*N)whereN是列表的大小。

排序列表的创建发生在编译时发生一次。所以,订单语句是O((R * logN) + N * logN))。我相信假设是R>> N,所以它在表达中占主导地位。换句话说,因为排序发生了一次,并且针对每一行查看算法,编译工作就放弃了。

于 2013-08-11T16:10:00.173 回答