Mysql IN子句与自动增量ID的范围
Posted
技术标签:
【中文标题】Mysql IN子句与自动增量ID的范围【英文标题】:Mysql IN clause vs range for auto increment ID 【发布时间】:2015-03-11 04:48:20 【问题描述】:我有一个大约 5000 万行的 mysql 表(预计会增长)。现在我需要遍历整个表。我正在尝试分块迭代,即获取 N 行,处理,再获取 N 行
该表具有自增整数 ID 作为主键。这将使迭代更容易。我的问题是:哪个语句会更快(循环计数器在哪里):
SELECT * FROM table WHERE ID IN (i, i+1, ..., i+N)
或
SELECT * FROM table WHERE ID >= i AND ID < i + N
第一个使用IN
子句,它对主键进行查找,我认为这非常快。第二个具有小于+大于条件的条件,对于非索引列将非常慢。但是由于我是在主键上做的,所以我不确定性能。
其中哪一个应该提供更好的性能,比如N = 1000
?
【问题讨论】:
何不亲自试一试,分析结果? 也这样做,但想知道是否有人可以对它进行一些理论上的解释...... 第二个版本。你真的应该花一点时间学习B-tree 数据结构(这是 MySQL 索引的实现方式):很明显,从这种结构中定位一个范围是 O(log n),而定位 m 个特定节点—虽然不是 *hard* — 仍然是 O(m*log n)。 【参考方案1】:使用这个:
SELECT * FROM table WHERE ID >= $i AND ID < $i + $N
“范围扫描”很高兴找到第一行(在$i处),然后得到Next,Next,...非常高效。
但是,这确实假设 ID 是密集的。如果您删除了很多行,您可能不会每次都使用 $N 行。 (是的,你可以说这无关紧要。)
$N = 1000 -- 这是一个合理的数字 -- 您没有花费“太长时间”,也没有“阻塞”太多行。等等。
有关其他技术(例如不密集时),请参阅my blog on deleting in chunks。
【讨论】:
当然,无论密度如何,总是有一定大小的块可以使用SELECT * FROM table WHERE ID >= $i LIMIT 1000
,使用前一个块中的最大ID
作为$i
的下一个值。跨度>
以上是关于Mysql IN子句与自动增量ID的范围的主要内容,如果未能解决你的问题,请参考以下文章