在日常的开发工作中,我们经常会遇到从数据库中随机获取几条数据的情况。
常用的方式是使用MySQL
的ORDER BY RAND()
语句来随机获取数据,该语句来获取随机数据,可能会对性能产生一定的影响,特别是在数据量较大的情况下。
因此,在实际应用中,我们需要根据具体情况进行权衡和优化。
随机取数的场景
随机展示数据
如果你有一个数据表存储了用户的信息,你可以使用随机获取数据的方式来展示一些用户的信息,增加页面的趣味性和多样性。
随机推荐
如果你有一个商品表,你可以使用随机获取数据的方式来推荐一些商品给用户,增加用户的购买兴趣和体验。
随机抽奖
如果你有一个参与抽奖的用户表,你可以使用随机获取数据的方式来选择中奖用户,确保公平性和随机性。
随机排序
如果你有一个文章表,你可以使用随机获取数据的方式来对文章进行随机排序,增加用户的阅读体验和发现性。
模拟测试数据
增加数据库表
这里新建一张users
表,只有id、name、age、email几个字段;
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50),
age INT,
email VARCHAR(100)
);
增加存储过程
为了方便演示,能够区别出不同的SQL查询出来的效率,这里使用存储过程,批量写入300万条数据
DELIMITER //
CREATE PROCEDURE execute_sql_loop()
BEGIN
DECLARE i INT DEFAULT 0;
WHILE i < 3000 DO
INSERT INTO users (name, age, email)
SELECT
CONCAT('user', UUID_SHORT()) name,
FLOOR(RAND() * 100) age,
CONCAT('user', UUID_SHORT(), '@example.com') email
FROM (
SELECT t1.*
FROM
(SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10) t1,
(SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10) t2,
(SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10) t3
) tt;
SET i = i + 1;
END WHILE;
END //
DELIMITER ;
调用存储过程
CALL execute_sql_loop();
几种方式效率对比
测试表有 300 万条数据,各个SQL的执行效率如下
方式一
最简单,但是效率最低
执行时间:3.098s
SELECT * FROM users ORDER BY RAND() LIMIT 10
方式二
查询效率较高,但会产生连续的数据
执行时间:0.310s
SELECT
t1.*
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 ASC
LIMIT 10;
方式三
查询效率次之,不会产生连续数据
执行时间:0.296s
SELECT
*
FROM
users
WHERE
id >= ( SELECT floor( RAND() * ( SELECT MAX( id ) FROM users ) ) )
ORDER BY
id
LIMIT 10;
总结
方式一与方式二的查询效率,相差了进10倍;
方式二与方式三的查询效率基本没有差别;
如何在生产环境中有随机获取数据的场景,尽量使用方式二和方式三;