MYSQL随机读取一条数据

    xiaoxiao2023-11-08  148

    项目上有个需求,需要在客户表中随机取一条数据,虽然不是我的活,但是也思考了一下,本来觉得挺简单的,大抵是使用rand函数之类的就可以搞定,但是查了查资料,还真是别有洞天。看了几篇博客,下面介绍几种方式:

    方式一:

    select * from users order by rand() LIMIT 1

    好吧,这是第一种方式,也是最低效的方式,完全不考虑sql的性能,运行时间长,而且mysql官方文档已经声明很不建议使用这种方式了。

    方式二:

    SELECT * FROM users AS t1 JOIN (SELECT ROUND(RAND() * ((SELECT MAX(userId) FROM `users`)-(SELECT MIN(userId) FROM users))+(SELECT MIN(userId) FROM users)) AS userId) AS t2 WHERE t1.userId >= t2.userId ORDER BY t1.userId LIMIT 1

    鉴于rand的取值,所以加上了round函数进行整数约束,当然还可以加上floor等都可以,执行该sql语句,用时0.031s,效率没说的,相当的给力!心里那个爽啊,紧接着,我把”LIMIT 1“改为了”LIMIT 100“ 随机取一百条记录,用时0.048,给力吧。可是就在此时问题出现了,发现结果好像不是随机的?为了验证结果,又执行了N次,真不是随机的, 问题出现在”ORDER BY t1.userId“这里,按userId排序了。随机取一条记录还是不错的选择,多条就不行了啊!

    方式三:

    SELECT * FROM users WHERE userId >= ((SELECT MAX(userId) FROM users)-(SELECT MIN(userId) FROM users)) * RAND() + (SELECT MIN(userId) FROM users) LIMIT 1

    第三种方式比较好懂一点,用差值做随机,然后加上最小值,这样userId的值域就会落在最大值和最小值之间,执行该sql语句,用时0.039s,效率太给力了!接着我就把”LIMIT 1“改为了”LIMIT 10000“,用时0.063s。经过多次验证,哥对灯发誓,结果肯定是随机的!

    结论:方法1效率不行,切忌使用;随机获得一条记录,方法2是相当不错的选择,采用JOIN的语法比直接在WHERE中使用函数效率还是要高一些的,不过方法3也不错;

    思考:目前处理的情况都是主键连续且为数字的数据,但是对于以UUID作为主键的数据表,这种方式貌似就不能胜任,没有主键的最大值和最小值,就缺少了随机的条件,这就不能使用上面的方式了,期待留言,提供解决方案或者思路

    最新回复(0)