我有这个需求:
数据库中的uid离散分布不连续,需要随机select某一条记录。
1、最懒做法
select uid, uname from user order by RAND() limit 1
这个非常慢,因为几乎要遍历整个表。
2、用id随机范围。
其实如果我们能得到min(uid)和max(uid),然后随机这之间的某一个ID,再where >= 就可以了。
首先是获取min和max的uid:
select min(uid), max(uid) from user;
然后是获取[min, max]之间的随机数。
select min(uid)+floor(RAND()*(max(uid)-min(uid))) from user;
上面这句执行非常慢,
+----+-------------+-------+-------+---------------+---------+---------+------+--------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+---------+---------+------+--------+-------------+ | 1 | SIMPLE | user | index | NULL | PRIMARY | 4 | NULL | 921162 | Using index | +----+-------------+-------+-------+---------------+---------+---------+------+--------+-------------+ 1 row in set (0.00 sec)
需要优化:
select ceil(rand()*(select max(uid) from user));
然后加上where
select uid, uname from user as r1 join (select min(uid) as min, max(uid) as max from user) as r2 where r1.uid >= r2.min+floor((r2.max-r2.min)*RAND()) limit 0,1;
最后这句非常快了。