mysql随机获取一条或者多条数据SQL分析 关于mysql随机获取多条数据的学习记录。
1.SQL 首先记录一下找到的三种sql语句
1. 简单使用random() SELECT * from usertb order by rand () LIMIT 100
语句虽然能够实现需求,但是根据一些资料看到 ORDER BY从句里面不能使用RAND()函数,这样会导致数据列被多次扫描,导致效率相当相当的低,效率不行,切忌使用。
2. 随机获取连续的数据 SELECT * FROM usertb AS t1 JOIN (SELECT ROUND (RAND () * ((SELECT MAX (id ) FROM `usertb` )-(SELECT MIN (id ) FROM usertb))+(SELECT MIN (id ) FROM usertb)) AS id ) AS t2 WHERE t1.id >= t2.id ORDER BY t1.id LIMIT 100
3. 高效一点的随机获取多条数据 SELECT * FROM usertb WHERE id >= ((SELECT MAX (id ) FROM usertb)-(SELECT MIN (id ) FROM usertb)) * RAND () + (SELECT MIN (id ) FROM usertb) LIMIT 100
2.测试 1.创建测试表 但是在测试得到时候就发现,自己用的学习用的表数据量太小了,完全看不到效果SHIT
手动创建一个百万级的测试表
1 创建数据表(MYISAM方式存储插入速度比innodb方式快很多)
字段类型: id :编号 uname:用户名 ucreatetime: 创建时间 age:年龄 CREATE TABLE usertb( id serial , uname varchar (20 ) , ucreatetime datetime , age int (11 )) ENGINE =MYISAM DEFAULT CHARACTER SET =utf8 COLLATE =utf8_general_ci AUTO_INCREMENT=1 ROW_FORMAT=COMPACT ;
2 创建插入数据存储过程
delimiter $$ SET AUTOCOMMIT = 0 $$ create procedure test1() begin declare v_cnt decimal (10 ) default 0 ; dd:loop insert into usertb values (null ,'用户1' ,'2010-01-01 00:00:00' ,20 ), (null ,'用户2' ,'2010-01-01 00:00:00' ,20 ), (null ,'用户3' ,'2010-01-01 00:00:00' ,20 ), (null ,'用户4' ,'2010-01-01 00:00:00' ,20 ), (null ,'用户5' ,'2011-01-01 00:00:00' ,20 ), (null ,'用户6' ,'2011-01-01 00:00:00' ,20 ), (null ,'用户7' ,'2011-01-01 00:00:00' ,20 ), (null ,'用户8' ,'2012-01-01 00:00:00' ,20 ), (null ,'用户9' ,'2012-01-01 00:00:00' ,20 ), (null ,'用户0' ,'2012-01-01 00:00:00' ,20 ) ; commit ; set v_cnt = v_cnt+10 ; if v_cnt = 1000000 then leave dd; end if ; end loop dd ; end ;$$ delimiter ;
3 执行存储过程
4 修改engineer
alter table usertb engine =innodb ;
2.测试运行时间 首先运行最简单朴实无华的
在100万条数据中随机获取100条,平均运行时间为1.39
EXPLAIN 看那一下,好嘛所有数据都爬了一遍选了100条,order by random() 相当于不是根据某个字段来排序,而是乱序。但是这个方法可以帮助制造混乱分布的测试数据。
继续第二种语句,看到运行时间相比高效了不少,只要0.023s
但是查询出来的数据是连续的,如果需求是随机获取连续的几条数据倒是可以用这个
第三种语句
ok,也非常的高效。完美满足需求
其中很关键的思想就是取最大数到最小数之间的随机数了
换成java
代码也就是
Math.floor(Math.random() * (max - min) + min)