问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

MYSQL随机调用order by rand(),效率太低,有高效些的吗?

发布网友 发布时间:2022-04-29 00:49

我来回答

4个回答

热心网友 时间:2022-04-08 19:18

要从tablename表中随机提取一条记录,大家一般的写法就是:SELECT * FROM tablename ORDER BY RAND() LIMIT 1。

但是,后来我查了一下MYSQL的官方手册,里面针对RAND()的提示大概意思就是,在ORDER BY从句里面不能使用RAND()函数,因为这样会导致数据列被多次扫描。但是在MYSQL 3.23版本中,仍然可以通过ORDER BY RAND()来实现随机。

但是真正测试一下才发现这样效率非常低。一个15万余条的库,查询5条数据,居然要8秒以上。查看官方手册,也说rand()放在ORDER BY 子句中会被执行多次,自然效率及很低。
You cannot use a column with RAND() values in an ORDER BY clause, because ORDER BY would evaluate the column multiple times.
搜索Google,网上基本上都是查询max(id) * rand()来随机获取数据。
SELECT *
FROM `table` AS t1 JOIN (SELECT ROUND(RAND() * (SELECT MAX(id) FROM `table`)) AS id) AS t2
WHERE t1.id >= t2.id
ORDER BY t1.id ASC LIMIT 5;

但是这样会产生连续的5条记录。解决办法只能是每次查询一条,查询5次。即便如此也值得,因为15万条的表,查询只需要0.01秒不到。

下面的语句采用的是JOIN,mysql的论坛上有人使用
SELECT *
FROM `table`
WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM `table` )
ORDER BY id LIMIT 1;

我测试了一下,需要0.5秒,速度也不错,但是跟上面的语句还是有很大差距。总觉有什么地方不正常。

于是我把语句改写了一下。
SELECT * FROM `table`
WHERE id >= (SELECT floor(RAND() * (SELECT MAX(id) FROM `table`)))
ORDER BY id LIMIT 1;

这下,效率又提高了,查询时间只有0.01秒

最后,再把语句完善一下,加上MIN(id)的判断。我在最开始测试的时候,就是因为没有加上MIN(id)的判断,结果有一半的时间总是查询到表中的前面几行。
完整查询语句是:
SELECT * FROM `table`
WHERE id >= (SELECT floor( RAND() * ((SELECT MAX(id) FROM `table`)-(SELECT MIN(id) FROM `table`)) + (SELECT MIN(id) FROM `table`)))
ORDER BY id LIMIT 1;

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

最后在php中对这两个语句进行分别查询10次,
前者花费时间 0.147433 秒
后者花费时间 0.015130 秒
看来采用JOIN的语法比直接在WHERE中使用函数效率还要高很多。

热心网友 时间:2022-04-08 20:36

你的感受我也有,这个我也搞不定,但是公司遇到这种数据量很大的都去找软件商工程师解决,付给他们薪酬,我们再去试验调试,至于应用环境我不清楚,所以不能给你更多的建议了。但是从思想上来说,这段代码执行后,从数据库中选择的都是连续的,也就是说,他是一次执行后的结果,如果改成循环语句,每次只输出一个结果,然后循环次数设置为需要的随即结果数,然后对于结果进行有序排列,可以试试自己改改。

热心网友 时间:2022-04-08 22:11

先随机算出一批id号码。例如1201 3508 2222 3333,随便你怎么算,在客户端算也可以,在服务器端算也可以。然后取select * from table where id in(1201,3508,2222,3333...)

热心网友 时间:2022-04-09 00:02

这个很容易解决,不要用系统 的随机 rand,那个根本不算是真正意义 的随机

,自己产生随机 数就行了,方法几乎无数,比如楼上的
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
苹果电脑电池充不进电苹果电脑充不进去电是怎么回事 苹果电脑不充电没反应苹果电脑充电指示灯不亮充不了电怎么办 狗狗更加忠诚护家、善解人意,养一只宠物陪伴自己,泰迪能长多大... 描写泰迪狗的外形和特点的句子 国外留学有用吗 花钱出国留学有用吗 !这叫什么号 百万医疗赔付后是否可以续保 前一年理赔过医疗险还能续保吗? 医疗住院险理赔后还能购买吗? Mysql服务器如何得到最佳性能优化 跪求高手给出MySQL优化方案,7万多条查询很慢,查询代码如下,感激不尽... 如何提高mysql rand函数效率 mysql 语句ORDER BY rand() 优化方法? 忘记司法部和普通健康码打卡都如何补打卡啊? 广西健康码漏打卡一天怎么补回来? 投影仪怎么调颜色 投影仪颜色显示绿色怎么调? 投影仪投影颜色不对怎么办 投影仪怎样调解颜色和清晰度? vivitek投影仪怎么调色彩和电脑颜色一样? 煮熟肉的香料 和五香牛骨的香料。。。。奢求高品质配方,g给我回答的都长命百岁。。。先谢了 如何去牛排骨的腥味 五香牛骨汤 微信支付被司法机关限制了什么时候解除 怎么让自己的电脑声音更大 如何让windows 音量300% 500%甚至更大的运行? 如何将电脑声音调到%500? 小红书留言区怎么@朋友? OPPOReno5Pro换后盖多少钱?OPPO Reno5Pro后壳碎了,更换想要多少钱 mysql 查询 优化 鲁大师是不是杀毒软件?可不可以和杀毒软件一起装? 为什么一般用电烧的热水壶烧久了,壶内是黑色的? 创维双开门冰箱门上面的灯老闪咋回事? 创维对门冰箱里面灯不亮,显示屏也是一闪一闪的是怎么回事? 生活中很多人在注重养生,那应该怎么养生最好? 创维电视开机显示正在为您准备主页,屏幕还一闪一闪的是怎么回事?_百度问一问 南京创维冰箱显示UC 饮食促平衡,调节身体免疫力,平时该如何养生比较好? qq怎么调手机在线几个g 怎么养生呢? qq几g在线自己能改吗 qq怎么设置显示手机卡网是几g 姓李,中间要火字旁的字,后面也必须带木字旁的女孩名字 女生去上海上大学的必备物品 男生过生日女生送什么礼物好? 快穿主受,受前期很丑,后期通过系统做任务变好看,请问这个小说叫什么名字啊😮? 在拍拍贷在哪里找结清证明 打印机佳能TS308可以用墨粉吗? 女主可以随意改造外貌的快穿系统文