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 执行存储过程

call test1;

4 修改engineer

alter table usertb engine=innodb;

2.测试运行时间

首先运行最简单朴实无华的

image-20200424160433946

在100万条数据中随机获取100条,平均运行时间为1.39

EXPLAIN 看那一下,好嘛所有数据都爬了一遍选了100条,order by random() 相当于不是根据某个字段来排序,而是乱序。但是这个方法可以帮助制造混乱分布的测试数据。

image-20200424160550761

继续第二种语句,看到运行时间相比高效了不少,只要0.023s

image-20200424160737586

但是查询出来的数据是连续的,如果需求是随机获取连续的几条数据倒是可以用这个

第三种语句

image-20200424161425727

ok,也非常的高效。完美满足需求

其中很关键的思想就是取最大数到最小数之间的随机数了

换成java代码也就是

Math.floor(Math.random() * (max - min) + min)