不知道高版本的 mysql 里是否有了更简洁随机获取数据的解决方案?

2015-02-23 02:46:14 +08:00
 konakona
一直以来大概都是这样书写的:
select ...from a left join b on a.id = b.id ....where ... and a.id >= (select FLOOR( MAX(id) * RAND()) FROM b) GROUP BY a.id ORDER BY a.id DESC LIMIT 5

-,- 有些项目里需要随机获取的地方非常多,如果都这样写..实在是有些不够方便!

想了解下现在的mysql可以更快速方便便捷高效的提取随机数据了吗?
2874 次点击
所在节点    程序员
20 条回复
vzch
2015-02-23 02:53:16 +08:00
我觉得这不是 MySQL 的问题,这是子查询的效率问题
konakona
2015-02-23 03:02:45 +08:00
@vzch 你跑题了..
xiaogui
2015-02-23 03:25:41 +08:00
根据需求,重新审视各处随机获取信息的逻辑和设计,特殊情况下可以将随机逻辑放在数据库以外的地方处理。
就本例来讲,可能正如 @vzch 所讲,是子查询的问题。
konakona
2015-02-23 04:04:31 +08:00
@xiaogui 我说的是..mysql3之前的round()的场景..你们为什么只看到我的子查询? TAT
bombless
2015-02-23 05:26:29 +08:00
明明是floor(逃
xiaogui
2015-02-23 06:17:46 +08:00
@konakona 你如何判断出是随机处“不高效”呢?
msg7086
2015-02-23 08:29:48 +08:00
@xiaogui 因为ORDER BY RAND会扫全表。这是教科书式的错误写法了吧。
否则也不会出现撸主这样硬生生用子查询来提高效率的写法了。
xiaogui
2015-02-23 10:16:21 +08:00
@msg7086 所以我也很搞不懂楼主要干嘛
msg7086
2015-02-23 10:19:29 +08:00
@xiaogui 建议仔细反复阅读楼主的帖子。我觉得他说得挺明白了……
jevonszmx
2015-02-23 19:33:39 +08:00
每次随机查,性能损失太大了,真心解决不了的话,不如加个字段rand_sort,写个定时脚本批量更新一下排序值。
zhengkai
2015-02-23 20:17:30 +08:00
小项目不需要关心子查询效率,大项目不会用子查询

如果是范式你可以封装个函数,给定表名字段名,直接生成出 SQL

我碰到这类问题会习惯的去想,比方说最近一万条的数组放进 memcache,然后现取现随机

而且大部分场景,就算是随机,也会有根据时间调整展现几率的问题吧?
konakona
2015-02-23 21:17:15 +08:00
@xiaogui 我这么高端的sql都写出来了!标题那么闪烁!竟然还不知道我在问什么!呜呜呜呜!!!(why are you so diao!)


@zhengkai 围绕“随机拿几条数据”这个point出发!哪怕只有1000条数据,如果只是随机拿出5条,用Round()方法的话,性能非常低,预计大约需要至多1秒。而如果用我的sql(经过子查询多次优化结果后的方法),至多需要0.001秒。

所以,再小的项目也不能用Round(),因此在mysql3之后,已经取消了这个方法在ORDER BY中的使用(会报出Tips错误)。
msg7086
2015-02-23 21:49:52 +08:00
RAND()…
zhengkai
2015-02-23 23:43:20 +08:00
@konakona 我说的不是 rand 用不用子查询,是说的用 rand(也就必然包含子查询或者 inner join)。按我的标准用 rand 的都是小项目,而不需要再在所有用 rand 的项目里区分大小了

而且慢的原因是 mysql 没法自己优化,会把所有用不上的字段放在一起,所以 sort buffer 会非常大,极限情况就是表只有 id 这一个字段的时候不就不需要子查询了么。这个概念属于比较基础的知识,如果你是想说你这 SQL 很高端真不至于……这是老王2009年的blog http://hi.baidu.com/thinkinginlamp/item/1b9aaf09014acce0f45ba6d3 我在晚些时候知道是《高性能 MySQL》里说的

另外那叫 rand 不是 round……看到你两个回帖都写的 round ……
konakona
2015-02-24 01:00:27 +08:00
@zhengkai 你们扯的可真远,麻烦你再回头看看我的标题和内容...我一直在围绕Round()的问题进行讨论,可是你们都在说子查询,外漏了,麻烦大家好好看帖..

@msg7086 =.= 英文是因为我习惯了,我是团哥,有时根老外聊天,经常要打Round...
iannil
2015-02-24 02:01:05 +08:00
艾玛,刚撸了一遍那个31岁0基础好友买rmbp的帖子,这里显得好悠闲
xuhai951753
2015-02-24 17:26:03 +08:00
konakona
2015-02-24 22:31:13 +08:00
@xuhai951753 谢谢你还找了个帖子..不过请认真看我的帖子...=,=我的sql就是你找的帖子..
xuhai951753
2015-02-24 23:26:59 +08:00
@konakona 帖子最下不是给了个更快的sql语句么。 [虽然没实测过。。 [光速逃
konakona
2015-02-25 00:45:58 +08:00
@xuhai951753 -,- 我这sql就是啊..但是我发这个帖子的最主要原因是想追问下目前的mysql有没有比较简单的办法?=,= 真的, 每次都这样写,我记不住..

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/172242

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX