21

我有一组我想根据主键获取的连续行,主键是一个自动递增的整数。假设没有漏洞,之间是否有任何表现:

SELECT * FROM `theTable` WHERE `id` IN (n, ... nk); 

和:

SELECT * FROM `theTable` WHERE `id` BETWEEN n AND nk;
4

4 回答 4

17

BETWEEN IN在这种情况下应该表现出色(但也要测量和检查执行计划!),尤其是在n增长和统计数据仍然准确的情况下。让我们假设:

  • m是你桌子的大小
  • n是你的范围的大小

可以使用索引(n相比起来很小m

  • 理论上,BETWEEN可以对主键索引进行一次“范围扫描”(Oracle 说),然后最多遍历n索引叶节点。复杂度将是O(n + log m)

  • IN通常实现为n对主键索引的一系列(循环)“范围扫描”。随着m桌子的大小,复杂性总是O(n * log m)......这总是更糟(对于非常小的表格m或非常小的范围可以忽略不计n

不能使用索引(n是 的重要部分m

在任何情况下,您都会进行全表扫描并评估每一行的谓词:

  • BETWEEN需要评估两个谓词:一个用于下限,一个用于上限。复杂度是O(m)

  • IN最多需要评估n谓词。复杂性是O(m * n)......这总是更糟,或者O(m)如果数据库可以将IN列表优化为哈希图,而不是谓词列表。

于 2011-06-15T07:29:19.633 回答
16

a between b and c是一个扩展为 的宏b <= a and a <= c

a in (b,c,d)是一个扩展为 的宏a=b or a=c or a=d

假设您的nandnk是整数,那么两者最终的含义应该相同。between变体应该快得多,因为它只有两次比较,而不是变体nk - n的比较in

于 2010-07-22T11:29:54.870 回答
4

我已经针对这个问题进行了研究。我的表中有 11M 行。我对此执行了两个查询:

查询一:SELECT * FROM PLAYERS WHERE SCORE BETWEEN 10 TO 20

查询 2:SELECT * FROM PLAYERS WHERE SCORE IN (10,11,...,20)

在执行时间时,两个查询都被翻译为Andomar上面所说的。

在这两个查询中,查询 1 的运行速度比查询 2 快。

要了解更多信息,请点击此链接:

MySQL 中 BETWEEN VS IN() 的性能

谢谢你。

于 2014-12-02T11:50:16.930 回答
0

在许多数据库服务器中,IN() 只是多个 OR 子句的同义词,因为两者在逻辑上是等价的。在 MySQL 中并非如此,它对 IN() 列表中的值进行排序并使用快速二进制搜索来查看值是否在列表中。这是列表大小的 O(Log n),而等效的一系列 OR 子句是列表大小的 O(n)(即,对于大型列表来说要慢得多)

于 2020-10-29T17:06:12.063 回答