MySQL随机取数据的几种方法

1.order by rand()
数据多了极慢,随机性非常好,适合非常小数据量的情况。
2.SELECT * FROM table_name AS r1 JOIN (SELECT (ROUND(RAND() * (SELECT ABS(MAX(id)-MIN(id)-$limit) FROM table_name))+(SELECT MIN(id) from table_name)) AS id) AS r2 WHERE r1.id >= r2.id ORDER BY r1.id ASC LIMIT $limit;
速度非常快,但是得到的数据是id连续的,没办法解决。
子查询产生一个随机数。
rand()是0到1的随机数,可以等于0到1。
MAX(id)-MIN(id)还要要减去$limit以免结果数量不够$limit条
因为主表id可能不连续,所以r1.id要>=r2.id
还要注意的是有时候最小id不是从1开始的,可能从一个很大的数开始,所以必须加上M(id)的值
手册相关内容:若要在i ≤ R ≤ j 这个范围得到一个随机整数R ,需要用到表达式 FLOOR(i + RAND() * (j – i + 1))。例如, 若要在7 到 12 的范围(包括7和12)内得到一个随机整数, 可使用以下语句:
SELECT FLOOR(7 + (RAND() * 6));
3.select * from test where rand()<0.0005 limit 10;
0.0005是一个计算出的比例直接关系到随机的质量,比如数据表10000条数据,需要随机取300条,那么0.0005就需要改成(300/10000=0.03)。
这种方法不能保证每次能取到多少,需要取多次。这个应该是要扫表。几百万的数据量速度是非常快的。

百万级别2和3速度一样的快,主要区别是2总能返回limit条数据,3就没准了(符合正太分布)。2是连续数据,3是随机行。

3的话用1亿和3亿数据测试都在1分钟左右

mysql> select count(*) from gameLogin;
+-----------+
| count(*)  |
+-----------+
| 277222670 |
+-----------+
1 row in set (0.00 sec)

mysql> select id from gameLogin where rand()<0.0000001;
+-----------+
| id        |
+-----------+
|  15431983 |
|  68236783 |
|  83237035 |
|  98697590 |
| 151502399 |
| 166502644 |
| 181963230 |
| 234768030 |
| 249768278 |
| 265228883 |
+-----------+
10 rows in set (1 min 4.77 sec)

2的话理论上和数据量没关系,不过没有测试。用PHP随机id然后in()是没有性能损耗的

mysql> select * from gameLogin where id in(15431983 , 68236783 ,  83237035 , 98697590 , 151502399 , 166502644 ,181963230 , 234768030 , 249768278 ,265228883);
+-----------+----------+--------+----------+---------------------+----------------+
| id        | uid      | gameId | serverId | loginTime           | loginIp        |
+-----------+----------+--------+----------+---------------------+----------------+
|  15431983 | 30379812 |      1 |      794 | 2011-08-02 07:53:41 |                |
|  68236783 |  1953934 |      1 |     1233 | 2012-04-17 06:21:00 |                |
|  83237035 |  6121220 |      1 |     1491 | 2012-06-18 22:22:55 |                |
|  98697590 | 39005535 |      1 |     1865 | 2012-08-27 14:22:53 |                |
| 151502399 | 37553560 |     22 |     3776 | 2013-03-02 19:55:32 | 125.66.206.209 |
| 166502644 | 45051088 |     21 |     1201 | 2013-05-05 20:32:06 | 124.128.93.100 |
| 181963230 | 45812185 |     22 |     6116 | 2013-07-04 11:18:10 | 115.238.43.146 |
| 234768030 | 45453939 |     22 |     5778 | 2013-12-19 05:27:29 | 60.222.209.151 |
| 249768278 | 47917487 |     22 |    11852 | 2014-02-21 08:30:30 | 113.8.177.80   |
| 265228883 |  4022820 |      1 |     4573 | 2014-05-06 23:21:09 |                |
+-----------+----------+--------+----------+---------------------+----------------+
10 rows in set (0.08 sec)

 

MySQL随机取数据的几种方法》上有2条评论

  1. 我们的做法是交给php解决 不操作mysql 比如 一千w条数据 随机取十条 先用php生成一千万以内的随机数 20个 再用mysql的主键in(这20个随机数) 之所以取20条是因为有些id可能被删除了 然后再用php处理成10条 就完事
    ps:上午加你qq 要curl类了。。没给

发表评论

电子邮件地址不会被公开。

*