mysql 如何高效的 随机取数据?

2013-03-24 19:40:00 +08:00
 soho176
我想从文章列表里面随机取出固定数量的文章列表,现在的文章数量是200万,如何执行sql会高效/
不想用order by rand。
mysql对随机查询处理能力很差,遇到order by rand,就要全表扫描,性能非常差,容易给cpu耗死。
5450 次点击
所在节点    MySQL
13 条回复
lusin
2013-03-24 19:42:20 +08:00
先随机取0-200w的一些数字,再按ID取数据会不会快?
tysx
2013-03-24 21:21:30 +08:00
如果ID是连续的就随即取几个范围内的数字,然后select in
rqrq
2013-03-24 22:25:24 +08:00
网上遍地都是解决办法,有试过么?

SELECT * FROM tbl AS t1
INNER JOIN (
SELECT ROUND(RAND() * ((
SELECT MAX(id) FROM tbl
) - (
SELECT MIN(id) FROM tbl
)) + (
SELECT MIN(id) FROM tbl
)) AS id) AS t2
WHERE t1.id >= t2.id ORDER BY t1.id
LIMIT 1
soho176
2013-03-25 14:18:50 +08:00
id不是连续的,如果一个一个的取的话,那取的次数太多了,比如取10个随机文章就要查询数据库10次,效率有点低吧
dementrock
2013-03-25 14:46:58 +08:00
dementrock
2013-03-25 14:48:29 +08:00
或者给每个post都assign一个连续的fake_id?时间长了如果post有删除的话可以定期更新这些fake_id 反正不会有其它用途
min
2013-03-25 16:06:32 +08:00
效率低不怕,预先半夜跑好几百份随机列表,要用的时候几百份里面取一份呗
kisa77
2013-03-25 17:47:49 +08:00
分享一个以前用过的,1楼的方法如果主键非连续数字就不好使了

select SQL_NO_CACHE cid,account,country,companyname

FROM f_company as c

JOIN (select ROUND(rand() * ((SELECT MAX( cid )

FROM f_company))) as id) AS T

where c.cid >= T.id limit 10

当时是80万记录的f_company表(约780M)用时在0.006秒到0.016秒之间,可以接受
soho176
2013-03-25 18:08:51 +08:00
@min 几百份太少了,想让每个文章页面都放上随机文章10篇。
soho176
2013-03-25 18:23:10 +08:00
@rqrq 试过了几个都不理想,你的这个我刚试了 效率也低,随机取了10条,都用了0.05秒。
soho176
2013-03-25 18:35:59 +08:00
@kisa77 试了一下和2楼@rqrq 的效率差不多。
risent
2013-03-26 15:38:15 +08:00
楼主这种每个页面都要显示随机数据的话,数据库处理起来估计很难高效,可以尝试下Solr里面的RandomSortField。
napoleonu
2013-03-27 13:55:03 +08:00
你有自增主键ID么?如果有的话:

1.假设你每次需要随机50篇文章。
2.让程序随机出100个不重复ID,之所以是100个是防止某些文章删除了,可根据情况调整。
3.用select * from post where id in (2,3,5,7,11...) limit 50;取出文章。
4.好了。即使你运气比较差,随机的100个ID里面有60篇文章被删除了,那就随他去吧,who care?

如果没有自增ID,那么就调整业务加一个,不管是针对业务需求还是数据库性能优化都有好处,之后再使用上面的方案。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/63911

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX