Mysql 表中随机取数据记录

来源:互联网 发布:淘宝新店三个月扶持 编辑:程序博客网 时间:2024/04/29 21:06

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;
select round(2.555) from dual;
2.SELECT * 
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
0 0
原创粉丝点击