为什么IN()被认为是O(logN)操作?

时间:2013-08-11 15:52:45

标签: mysql performance optimization query-optimization

进一步研究this question我在High Peformance MySQL一书中找到了以下内容(第219页):

  

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

它认为这种方法是最优的,在列表大小中测量为O(logN),并且这是一种非常好的方法(而不是转换为一系列OR语句)。
但似乎忽略了列表的排序为O(NlogN),因此结果比执行一系列OR O(N)更糟糕。 我在这里误会了什么?
为了清楚起见,这个目标是列表是来自另一个SELECT

的巨大结果集

1 个答案:

答案 0 :(得分:5)

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

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

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