使用IN

时间:2017-06-19 15:09:16

标签: mysql optimization

例如:

SELECT UserID, count(*) FROM Messages WHERE UserID IN (3,6,8,11,12,13, ...)

我想如果你遇到MySQL max查询(数据包?)大小问题,但就优化而言,当有大量ID时,有更好的方法可以做到这一点,也许是通过创建临时表,插入ID并进行连接?如果是这样,另一种方法是什么,切换到另一种方法的截止点是什么?

2 个答案:

答案 0 :(得分:1)

根据MYSQL OR vs IN performance,IN是最快的方法。它还表明你可以在IN中使用数千个值来完成此操作;你必须更加具体地了解"很多",但我不认为这是一个实际限制。

我知道这样做的四种方式:

IN - 速度最快,最具可读性。

OR - 更慢,更不易读 - 特别是在复杂的where子句中。

UNION

SELECT UserID, count(*) FROM Messages WHERE UserID = 3
UNION
SELECT UserID, count(*) FROM Messages WHERE UserID = 6
UNION 
...

再次,更难阅读,可能更慢。

最后,将所需的ID插入临时表中。额外的I / O,以及在临时表等上创建索引几乎可以肯定意味着它会明显慢于IN。

答案 1 :(得分:1)

我在IN列表中看到了70K项。但它开始表现出低迷。

我会重新设计事物的流程,以便你的500K ID落在一张桌子上(可能是临时表)。然后我会做JOIN

MySQL代码中存在各种限制,但大多数都非常高,以至于用户很少使用它们。你正在强调一个我所见过的领域。

我认为代码在IN列表的内存中构建了一个数组,然后执行二进制搜索。这应该很好地扩展并且有效。但是这个临时数组的大小可能将内存分配推送到“交换”点。交换对MySQL来说非常糟糕。

我也非常确定它会在构建该数组时对数字进行重复数据删除。

是的,有一个可调参数VARIABLE可以控制SQL语句的最大长度,但只需要几MB;默认值可能是16MB,所以500K不会呱呱叫。

你还没有尝试过吗?如何使用1M随机值进行尝试。