如何高性能的将多对多查询后的结果集进行随机抽取?

表架构如下:
一个 Tag 表,一个 Detail 表,和一个中间表,多对多关系。
Detail 表有十几万数据,Tag 表几百条数据,中间表就多了,上百万条

通过一个Tag表的ID,可以查询出该tag表所关联的所有Detail数据:

Tag::find($request->id)->detail()  //查询出几万条数据

下面通过各种方法来尝试随机获取:

第一种:inRandomOrder(),这是一个构造器自带的方法,结果测试,效率极低,大概需要三秒左右

Tag::find($request->id)->detail()->inRandomOrder()->limit(6)->get()

第二种:构造器的orderBy()加DB::raw(‘RAND()’),经过测试,在结果集数据量大时效率依旧不高,大概两秒左右

Tag::find($request->id)->detail()->orderBy(DB::raw('RAND()'))->limit($num)->get()

第三种:使用程序随机几个ID,在使用whereIn去查询,这样效率是很高,但我多对多查询后的结果集ID并不是连续的,因此该方法应该行不通!!!!!

$randArr = [1, 124, 8512, 34, 12];  //假装随机
return Tag::whereIn("id", $randArr)->get();

第四种:百度找到一条效率很高的Mysql,貌似能利用来对现有结果集进行随机抽取ID,但我并不会用查询构造器对这条语句进行利用,从而使得查询的对象由某个表变为多对多查询后的结果集。

SELECT * FROM video WHERE id IN (SELECT id FROM (SELECT id FROM video ORDER BY rand() LIMIT 3) t)

我是个小前端,对mysql和laravel研究不是很深,请各位大佬有好的方法或能从上面的几种思路中精简提炼出可用方法,万分感谢!!!

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
最佳答案
User::query()->whereIn('id', User::query()->select('id')->orderByRaw('rand() LIMIT :nums', 3)->get())->get()

凑合用

2年前 评论
LuckyUser (楼主) 2年前
讨论数量: 3
User::query()->whereIn('id', User::query()->select('id')->orderByRaw('rand() LIMIT :nums', 3)->get())->get()

凑合用

2年前 评论
LuckyUser (楼主) 2年前

关联表 加 索引了嘛

2年前 评论
LuckyUser (楼主) 2年前
AyuAyu (作者) 2年前

楼上的方案确实会快一些吗?

2年前 评论
LuckyUser (楼主) 2年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!