在 MySQL中,从10 万条主键不连续的数据里随机取 3000 条,如何做到高效?

来源:互联网 发布:买淘宝账号 编辑:程序博客网 时间:2024/03/28 21:13

看到知乎上有人提问 

几百万记录的表,每天大概有10万条记录发生更新,从这10万条里随机取3000条做数据分析,

select id from table where date_refresh = 20120329 order by rand() limit 0,3000

这个sql执行起来会很慢,大概三四十秒吧,怎么优化?


这个也算是MySQL的一个经典问题了。


上面这种做法是非常不明智的做法,因为RAND()函数的随机因子变成这个表总数据量,所以速度会非常慢,跟读取多少条记录不是特别大的关系;


这个问题解决的基本思路是:

SELECT id FROM table WHERE date_refresh = 20120329
取出当日更新的10万 id (date_refresh 需要建立索引),放内存里面随机 shuffle 一下,顶多占用几 MB 内存,取前 3000 个,然后 
SELECT * FROM table WHERE id IN (id_0, id_1, id_2, ..., id_2999)


有个回答特别好, 翻译了国外一个牛人的文章  http://shiningray.cn/order-by-rand.html


主要的思路是,如果id是连续分布,那直接根据max(id)进行获得随机id,然后直接取出

如果id不连续,存在空挡,那么可以总是选择比随机出的id大(或小)的记录

如果id不连续,且必须尽可能平均地获取记录,那么需要额外做一个表,将不连续的id映射成连续id,然后进行随机

阅读全文
0 0
原创粉丝点击