处理业务中,有这样的需求,例如:有100W甚至更多的用户,此时我们要随机一条男性或者女性用户出来做数据操作。基于这个需求,我们做一下实验。
准备一张用户表,结构如下
简单写个MySQL储存
具体步骤:
查看下自己的储存
原始简单粗暴的 SQL 语句 select * from user order by RAND() LIMIT 1; (切勿使用)
mysql> select * from user order by RAND() LIMIT 1;
+--------+----------------------------------+------+--------+-------------+
| uid | name | age | gender | create_time |
+--------+----------------------------------+------+--------+-------------+
| 318393 | 48f8b305de34c87af8143fe1f24732ad | 24 | 0 | 2017 |
+--------+----------------------------------+------+--------+-------------+
1 row in set (17.19 sec)
mysql>
简单分析下:
type => all 呵呵,全表扫描 1000340 条数据
key => null 且没有索引,我们是随机查询
MySql 手册专门有提醒在 Order by 后面不能使用 RAND() 函数,会导致全表扫描
简单优化 SQL 语句, 使用join
以上测试发现快了不少,来分析下这个SQL语句,该SQL 语句的核心 Join和随机,随机的基本公式: RAND()*(max-min)+mix,随机出一个 uid as u2 然后 条件查询,uid 自建索引,效率蛮高的。
如果想随机多条呢?修改LIMIT?来看看
如果使用以上的SQL语句,发现查询到的数据是连续的,我们要的是随机的,不难理解 LIMIT 5 得到当前查询条件的前五条,所以是相对连续的,uid 是自增的,因为用的是储存插入的,实际项目也是相对连续的。这条SQL 一次性查询无法达到我们的需求,则可分别一条条查询,如果要求的随机条数较多,那就不建议使用该条SQL语句了。
再来一条SQL语句
explain 下
看看随机多条
随机多条也是完美的,随机核心就是用 RAND() 随机出一个用户uid,或则随机区间,然后再进行limit 即可