1.SELECT * FROM table_name ORDER BY rand() LIMIT 5;
这个应该是每条都随机,所以随机的效果是很好,但是参照网络上的实验,15万数据查询5条需要8秒,效率未免太低。
rand()函数 无论有没有参数 返回的都是一个0-1的浮点数。
round(d, n)根据n要保留的位数对d四舍五入 这个可以自己在终端中查询一次 例如
select round(2.555,2) from dual;
2. SELECT *select round(2.555) from dual;
FROM ` table ` AS t1 JOIN ( SELECT ROUND ( RAND () * ( SELECT MAX ( id ) FROM ` table ` )) AS id ) AS t2
WHERE t1 . id >= t2 . id
ORDER BY t1 . id ASC LIMIT 5 ;
这种方法很显然join就是为了得到一个随机的ID然后 取这个ID后面连续5个,一是这个随机不够彻底,二是,如果你的id不是连续的而是相差很大,你很有可能会连续取到多个相同的结果集,因为你四舍五入取到的那个数 很可能在一个范围很大的不连续区间中,只要你最后取得的ID是相同的,那么你就回不断的返回相同的结果集。这个采用了join效率15万条不到0.01秒
3.还有一种SELECT * FROM `table`
WHERE id >= (SELECT floor(RAND() * (SELECT MAX(id) FROM `table`)))
ORDER BY id LIMIT 1;
这种是下面这种的改进版:
SELECT *
FROM `table`
WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM `table` )
ORDER BY id LIMIT 1;
上面查询15万条只需要0.01秒,而下面的需要0.5秒。
4.
SELECT * FROM `table`
WHERE id >= (SELECT floor( RAND() * ((SELECT MAX(id) FROM `table`)-(SELECT MIN(id) FROM `table`)) + (SELECT MIN(id)FROM `table`)))
ORDER BY id LIMIT 1;
SELECT *
FROM `table` AS t1 JOIN (SELECT ROUND(RAND() * ((SELECT MAX(id) FROM `table`)-(SELECT MIN(id) FROM `table`))+(SELECT MIN(id) FROM `table`)) AS id) AS t2
WHERE t1.id >= t2.id
ORDER BY t1.id LIMIT 1;
我们注意到 下面又是应用了 join关键字,把limit改为10前者花费0.147433 秒,后者花费0.015130 秒
看到还有人这样实现:
首先,需要计算表中的总行数和你想要的得到随机行数。其次,在 WHERE 子句中加入该碎片数字,并要求结果只能小于(或等于)从这个碎片数字。
例如,假设你有一个20万行的表,你只需要从表中随机100行。这个碎片数是从100/总行数得到:100 / 20万= 0.0005。
该查询将如下所示:SELECT col1 FROM tbl WHERE RAND() <= 0.0005;
为了得到准确的100行结果集,我们可以增加碎片数字和 limit限制:例如
SELECT col1 FROM tbl WHERE RAND()<=0.0006 limit 100;
再延伸探讨一下,假如是随机取5条数据,但是要求每次取出的5条数据不重复呢?上面的方法虽然基本不会重复,但是不是100%,记录总数越少,重复的概率越大
比如有100行记录的号码表,每次随机取8个号码,换一批再取8条,用上面方法,有时会重复
想一个比较笨的方法:如果数据量少又允许8个号码记录连续,那么用limit X,N,让这个X从0,8,16,......,这样到也行,但是如果数据量大了,这方法效率就太低了
参考: http://blog.csdn.net/jiao_fuyou/article/details/24377127