工作中会遇到从数据库中随机获取一条或多条记录的场景,下面介绍几种随机获取的方法供参考。
首先创建个 users 表演示:
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
表中存放30万记录。
SELECT * FROM users ORDER BY RAND() LIMIT 1;
LIMIT 1 的执行时间:0.559s, LIMIT 100 耗时 0.660s。
此种方法在数据量小的情况下可以使用,但在生产环境不建议使用。
MYSQL 手册里面针对 RAND() 的提示大概意思就是,在 ORDER BY 从句里面不能使用 RAND() 函数,因为这样会导致数据列被多次扫描,导致效率相当相当的低,效率不行,切忌使用。
SELECT * FROM users AS t1 JOIN (SELECT ROUND(RAND()*(SELECT MAX(id)
FROM users)) AS id) AS t2 WHERE t1.id>=t2.id ORDER BY t1.id LIMIT 1;
此 sql 随机获取一条的时间是 0.014s,LIMIT 100 时耗时 0.020s,性能上没差多少。
获取多条的话有时会达不到要求(获取的记录数可能达不到多条)
SELECT * FROM users as t1 WHERE t1.id>=(RAND()*(SELECT MAX(id) FROM users)) LIMIT 1;
随机取一条的耗时:0.015,LIMIT 100 时耗时 0.026s。
随机获取一条记录推荐使用 第 2 种方法,在 30 万条记录时也只需 0.014s。
2021.06.02 更新:
上边第二种方法更优写法:
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
第三种方法的更优写法:
SELECT * FROM users WHERE userId >= ((SELECT MAX(userId) FROM users)-(SELECT MIN(userId) FROM users)) * RAND() + (SELECT MIN(userId) FROM users) LIMIT 1
via: MySQL数据库中随机获取一条或多条记录_River106的博客-CSDN博客_mysql随机取一条记录 https://blog.csdn.net/angellee1988/article/details/103845533
MYSQL随机读取一条数据_shenzhou_yh的博客-CSDN博客_mysql 随机查询一条数据 https://blog.csdn.net/shenzhou_yh/article/details/90550090