要做随机取数据,想到了SELECT * FROM tablename ORDER BY RAND() LIMIT

但是官方不建议在order by中使用rand(),如ORDER BY RAND()。查询效率极其低下,解释如下:

works for small tables, but once the tables grow larger than 300,000
records or so this will be very slow because MySQL will have to process
ALL the entries from the table, order them randomly and then return the
first row of the ordered result, and this sorting takes long time.
Instead you can do it like this (atleast if you have an auto_increment PK):

大概意思就是,会扫描全表再做随机排序。

网上的解决办法

SELECT * FROM ‘table’ WHERE id >= (SELECT floor(RAND() * (SELECT MAX(id) FROM ‘table’)))  ORDER BY id LIMIT 100;

但是这种方式也会产生问题,实际效果并不是随机取。具体可以自己试试,5.7.11以上会出现。考虑到有可能是mysql的一个bug,我去官网上查issue。发现已经有人提bug单了。https://bugs.mysql.com/bug.php?id=86624。那个人也发现,当子查询中有rand()时,每次引用到rand()都会重算一次。但是这个bug单,官方似乎不以为意,已经一年多没人回复了。只是MySQL的高级首席工程师Roy Lyseng在结尾提出了权衡的解决方案:对于5.7的版本,在子查询中加上limit,这个问题就可以解决了。对于8.0及以上的版本,可以使用NO_MERGE特性来解决这个问题。

最后解决方式如下

SELECT * FROM table , (SELECT RAND()*MAX(id) as id FROM table) AS p WHERE table.id >p.id LIMIT 100

发表评论

邮箱地址不会被公开。 必填项已用*标注